EDIT:
To make this whole thing clear, what im trying to do it make the program go to http://www.ultimateprivateservers.com/index.php?a=in&u=IkovPS and click the red "enter and vote" button
What I'm trying to do is access a webpage programmatically and click a href button that goes like this:
Enter and vote
I've looked at a few tuts with htmlUnit and I can't seem to get this working. What am I doing wrong? Could someone point me in the right direction? I'm not very good with java so it will get confusing.
Here is my code:
import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftware.htmlunit.html.*;
public class HtmlUnitFormExample {
public static void main(String[] args) throws Exception {
WebClient webClient = new WebClient();
HtmlPage page = webClient.getPage("http://www.ultimateprivateservers.com/index.php?a=in&u=IkovPS");
HtmlLink enterAndVoteButton =
page.getElementByName("btn btn-danger");
page=enterAndVoteButton.click();
HtmlDivision resultStatsDiv =
page.getFirstByXPath("//div[#id='vote_message_fail']");
System.out.println(resultStatsDiv.asText());
webClient.closeAllWindows();
}
}
and here is the console log:
SEVERE: IOException when getting content for iframe: url=[http://a.tribalfusion.com/p.media/aPmQ0x0qPp4WYBPGZbE4PJZdodZanVdfb0bQjYrBeXaisRUvDUFB5WHn0mFBoRU7y1T3s5TUj2qfXmEjIYbYgUHBUoP7Cns7uptfG5Evl5teN5ABLpbbL0V7R1VF3XGjNmqJQ3FQ2WFJBW6Q2QEf1ScUMQdUOYtbuTPbx2G32XrnZcVmun4PQgQmnH4HQrXHBAMTAJplZd1Wp/3002246/adTag.html]
org.apache.http.client.ClientProtocolException
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:188)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
at com.gargoylesoftware.htmlunit.HttpWebConnection.getResponse(HttpWebConnection.java:178)
at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseFromWebConnection(WebClient.java:1313)
at com.gargoylesoftware.htmlunit.WebClient.loadWebResponse(WebClient.java:1230)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:338)
at com.gargoylesoftware.htmlunit.html.BaseFrameElement.loadInnerPageIfPossible(BaseFrameElement.java:184)
at com.gargoylesoftware.htmlunit.html.BaseFrameElement.loadInnerPage(BaseFrameElement.java:122)
at com.gargoylesoftware.htmlunit.html.HtmlPage.loadFrames(HtmlPage.java:1993)
at com.gargoylesoftware.htmlunit.html.HtmlPage.initialize(HtmlPage.java:238)
at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseInto(WebClient.java:475)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:342)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:407)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:392)
at HtmlUnitFormExample.main(HtmlUnitFormExample.java:7)
Caused by: org.apache.http.HttpException: Unsupported Content-Coding: none
at org.apache.http.client.protocol.ResponseContentEncoding.process(ResponseContentEncoding.java:98)
at org.apache.http.protocol.ImmutableHttpProcessor.process(ImmutableHttpProcessor.java:139)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:200)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186)
... 14 more
Apr 18, 2015 5:28:37 AM com.gargoylesoftware.htmlunit.IncorrectnessListenerImpl notify
WARNING: Obsolete content type encountered: 'application/x-javascript'.
Exception in thread "main" com.gargoylesoftware.htmlunit.ElementNotFoundException: elementName=[*] attributeName=[name] attributeValue=[btn btn-danger]
at com.gargoylesoftware.htmlunit.html.HtmlPage.getElementByName(HtmlPage.java:1747)
at HtmlUnitFormExample.main(HtmlUnitFormExample.java:10)
Any help is much appreciated.
I took a look at the page and was able to cast a vote using a slightly different method. I prefer to use Selenium (http://www.seleniumhq.org/download/). I was able to use Selenium in Java to successfully cast a vote using the very crude code below. You can edit and optimize this code to your specific needs. I watched the whole process in an Internet Explorer driver but you could also use PhantomJS (http://phantomjs.org/download.html) as your driver if you do not want the window to show. Here is my simple code, the second argument of the setProperty method is the path to your driver executable this will be unique to your computer (you can download the IE driver on the Selenium downloads page as well):
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.support.ui.Select;
public class SeleniumTest()
{
public static void main(String[] args)
{
try
{
System.setProperty("webdriver.ie.driver"," IEDriverServer.exe");
WebDriver driver = new InternetExplorerDriver();
driver.get("http://www.ultimateprivateservers.com/index.php?a=in&u=IkovPS");
Thread.sleep(3000); //use the wait as shown below
WebElement button = driver.findElement(By.linkText("Enter and vote"));
button.click();
driver.close();
driver.quit();
}catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
A better way to wait for the page to load would be like this:
WebElement button = wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText("Enter and vote")));
You could also find the button using the class like:
WebElement button = wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("btn-danger")));
Related
When I use the Playwright's codegen feature it traces my clickpath into a Java file. But the created file has the wrong syntax, so I can't compile it.
I start the codegen with:
mvn exec:java -e -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="codegen wikipedia.org"
And the inspector provides this code:
public class Example {
public static void main(String[] args) {
try (Playwright playwright = Playwright.create()) {
Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions()
.setHeadless(false));
BrowserContext context = browser.newContext();
page.navigate("https://en.wikipedia.org/wiki/Main_Page");
page.getByPlaceholder("Search Wikipedia").click();
page.getByPlaceholder("Search Wikipedia").fill("stackoverflow");
page.getByRole("button", new Page.GetByRoleOptions().setName("Go")).click();
assertThat(page).hasURL("https://en.wikipedia.org/wiki/Stack_Overflow");
}
}
}
But there is already the first error. The method getByRole requires an AriaRole as its first parameter, not a String. So it's easy to fix, but I think it's not the idea of the product to generate code and let the developer fix it.
In some YouTube tutorials the inspector generates only fill and click functions with powerful selectors inside.
Is there a way to change the generated output to a specifc "code-style"? Or is there another reason why other people get nice working code and I don't?
My dependency:
<dependency>
<groupId>com.microsoft.playwright</groupId>
<artifactId>playwright</artifactId>
<version>1.27.0</version>
</dependency>
Sorry if I am wrong. But you should get something like this from an inspector which compiles fine
package org.example;
import com.microsoft.playwright.*;
import com.microsoft.playwright.options.*;
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
import java.util.*;
public class Example {
public static void main(String[] args) {
try (Playwright playwright = Playwright.create()) {
Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions()
.setHeadless(false));
BrowserContext context = browser.newContext();
// Open new page
Page page = context.newPage();
// Go to https://www.wikipedia.org/
page.navigate("https://www.wikipedia.org/");
// Click input[name="search"]
page.locator("input[name=\"search\"]").click();
// Fill input[name="search"]
page.locator("input[name=\"search\"]").fill("stackoverflow");
// Click button:has-text("Search")
page.locator("button:has-text(\"Search\")").click();
assertThat(page).hasURL("https://en.wikipedia.org/wiki/Stack_Overflow");
}
}
}
I'm trying to create a program to automate certain downloads, however, when using Selenium-WebDriver, I find I can't seem to find the element needed to log in. I have located the correct element, however actually using the WebDriver#findElement() is giving me issues.
<input id="form-username" class="form-field" form="popup-login" type="text" name="username" value="" tabindex="1" autofocus="">
I've been trying different By methods, however none of them work, along with different ID's, albeit to no avail.
I have checked other posts, but none of them seem to fit as they are just retrieving information from specific points in the HTML like a String, where I want to input information into it.
public void start(String usernameInfo, String passwordInfo) {
driver = new HtmlUnitDriver();
driver.get("https://www.nexusmods.com");
WebElement username = driver.findElement(By.id("form-username"));
username.sendKeys(usernameInfo);
username.submit();
WebElement password = driver.findElement(By.id("form-password"));
password.sendKeys(passwordInfo);
password.submit();
System.out.println(driver.getTitle());
driver.quit();
}
The output log can be viewed here: https://hastebin.com/zuvebosaha.nginx
UPDATE:
Tried ChromeDriver, and found the following code (modified for my use)
public void start(String usernameInfo, String passwordInfo) {
System.setProperty("webdriver.chrome.driver","C:\\Users\\veeay\\Documents\\chromedriver.exe"); //add chrome driver path (System.setProperty("webdriver.chrome.drive",chrome driver path which you downloaded)
WebDriver driver = new ChromeDriver(); // create object of ChromeDriver
driver.manage().window().maximize(); // maximize the browser window
driver.get("https://www.nexusmods.com/"); //enter url
driver.findElement(By.id("form-username")).sendKeys(usernameInfo); //type textbox's id or name or any locater along with data in sendkeys
driver.findElement(By.id("form-password")).sendKeys(passwordInfo);
driver.findElement(By.id("btnLogin")).click();
try {
Thread.sleep(2000); //used thread for hold process
} catch (InterruptedException e) {
e.printStackTrace();
}
driver.quit(); //for close browser
}
resulting in the following: https://hastebin.com/iliyuvucok.cs
UPDATE 2: Oddly enough, now that I actually post the question, I'm doing good. Now I can do everything except select the sign-in button.
public void start(String usernameInfo, String passwordInfo) {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\veeay\\Documents\\chromedriver.exe"); //add chrome driver path (System.setProperty("webdriver.chrome.drive",chrome driver path which you downloaded)
WebDriver driver = new ChromeDriver(); // create object of ChromeDriver
driver.manage().window().maximize(); // maximize the browser window
driver.get("https://www.nexusmods.com/Core/Libs/Common/Widgets/LoginPopUp?url=%2F%2Fwww.nexusmods.com%2F"); //enter url
driver.findElement(By.id("form-username")).sendKeys(usernameInfo); //type textbox's id or name or any locater along with data in sendkeys
driver.findElement(By.id("form-password")).sendKeys(passwordInfo);
driver.findElement(By.id("sign-in-button")).click();
try {
Thread.sleep(2000); //used thread for hold process
} catch (InterruptedException e) {
e.printStackTrace();
}
driver.quit(); //for close browser
}
apparently the sign-in button is not interactable https://hastebin.com/ahuvezoxat.cs
Added explicit wait and it works:
package vee;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Vee {
#Test
public void start() {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\pburgr\\Desktop\\selenium-tests\\GCH_driver\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
// new explicit wait
WebDriverWait webDriverWait = new WebDriverWait(driver, 5);
driver.get("https://www.nexusmods.com/Core/Libs/Common/Widgets/LoginPopUp?url=%2F%2Fwww.nexusmods.com%2F");
// using explicit wait
webDriverWait.until(ExpectedConditions.elementToBeClickable(By.id("sign-in-button")));
driver.findElement(By.id("form-username")).sendKeys("some name");
driver.findElement(By.id("form-password")).sendKeys("some password");
// print true or false by the button state
System.out.println(driver.findElement(By.id("sign-in-button")).isEnabled());
driver.findElement(By.id("sign-in-button")).click();
driver.quit();
}
}
Output:
Starting ChromeDriver 74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729#{#29}) on port 4301
Only local connections are allowed.
Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code.
[1560240089.419][WARNING]: This version of ChromeDriver has not been tested with Chrome version 75.
Čer 11, 2019 10:01:31 DOP. org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS
true
Maybe when repeating test, recaptcha pops up and disables the button.
I am kinda new to programming and I tried to execute the below code but chrome page is getting loaded but no execution happens and I am facing the below error.
Starting ChromeDriver 72.0.3626.69 (3c16f8a135abc0d4da2dff33804db79b849a7c38) on port 27651
Only local connections are allowed.
Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code.
Apr 19, 2019 12:23:41 AM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS
My config
windows 10, chrome driver V72 and selenium-3.141.59
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class MyClass {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver","C:\\Users\\ADMIN\\Desktop\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
String baseUrl = "http://demo.guru99.com/test/newtours/";
String expectedTitle = "Welcome: Mercury Tours";
String actualTitle = "";
actualTitle = driver.getTitle();
if (actualTitle.contentEquals(expectedTitle)){
System.out.println("Test Passed!");
} else {
System.out.println("Test Failed");
}
driver.close();
}
}
The logs you have posted are not errors. It is the log from the chrome driver.
As it is stated in the log, Detected dialect: OSS log level is INFO. It doesn't prevent your test from running.
The code you have posted should surely print in the console Test Failed.
In your code, you have not gone to the URL you have saved in the baseUrl variable. Before you get the title of the page, you should get the page. Otherwise, it won't give you the desired pages title.
Do the following and your code will load the page and will print Test Passed!
driver.get(baseUrl);
actualTitle = driver.getTitle();
After (foolishly) upgrading Appium Server along with various project libraries, such that I cannot tell which, if any, caused the problem, my previously running Appium framework suddenly started failing upon attempting to locate any elements.
The server starts (either manually via desktop or through the java code) and it launches my emulator (if not already loaded), makes the connection, opens the app (in the case show, simply settings) and fails as soon as it tries to validate that the settings main page is displayed by checking the existence of the "Settings" text:
Given the settings app is displayed (FAILED)
(java.lang.IllegalArgumentException: Can not set
io.appium.java_client.android.AndroidElement field
com.mindtree.pageobjects.SettingsMainPage.header to
org.openqa.selenium.remote.RemoteWebElement$$EnhancerByCGLIB$$d27c0df4)
The Appium server versions for both desktop and nodeJS is currently 1.7.2 I believe the problem started when I was originally at 1.7.1 or 1.7.2 and it succeeded in doing an auto-update on the desktop version to 1.8.1.
Selenium version is 3.11.0 (tried various flavors from 3.9.0 through 3.13.0)
Appium Java client is 6.0.0-BETA5 (tried 6.0.0-BETA4, 6.0.0, 6.1.0)
Java is 1.8
The JBehave test step that reports the error:
#Given("the settings app is displayed")
public void givenTheSettingsAppIsDisplayed() {
main = new SettingsMainPage(driver);
if (main.pageLoaded())
test.logGivenPass("the settings app is displayed");
else {
test.logGivenFail("the settings app is displayed");
fail();
}
}
The corresponding page object snippet:
public class SettingsMainPage extends MobilePageObject {
public SettingsMainPage(AndroidDriver<AndroidElement> driver) {
super(driver);
System.out.println("Settings Main page class has been initialized");
}
#AndroidFindBy(xpath = "//android.widget.TextView[#text='Settings']")
AndroidElement header;
#AndroidFindBy(id= "android:id/title")
List<AndroidElement> titles;
#AndroidFindBy(id= "android:id/summary")
List<AndroidElement> summaries;
public Boolean pageLoaded() {
return helper.isDisplayed(header);
}
}
Googling this particular error returns a few hits, but no offered solutions.
Any guidance appreciated.
edit: I should add that the failure seems to happen upon initialization of the page object via the page factory, since the text "initialized" is never shown, it fails while trying to initialize all the page elements, specifically the first one, at least according to the error message.
My base page object is below:
import java.time.Duration;
import org.openqa.selenium.support.PageFactory;
import com.mindtree.helpers.AppiumUtils;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.pagefactory.AppiumFieldDecorator;
public class MobilePageObject {
AndroidDriver<AndroidElement> driver;
AppiumUtils helper;
public MobilePageObject(AndroidDriver<AndroidElement> driver) {
this.driver = driver;
PageFactory.initElements(new AppiumFieldDecorator(driver, Duration.ofSeconds(15)), this);
helper = new AppiumUtils();
}
}
Edit Update: Downgraded the Appium Server through NodeJS from 1.7.2 to
1.7.1. Result: no change, same error reported.
I am using Appium server 1.8.1, selenium 3.13.0 and java client 6.1.0. I use the page object model like following and it works fine.
public class SettingsMainPage{
public SettingsMainPage(AndroidDriver<AndroidElement> driver) {
PageFactory.initElements(new AppiumFieldDecorator(driver), this);
System.out.println("Settings Main page class has been initialized");
}
#AndroidFindBy(xpath = "//android.widget.TextView[#text='Settings']")
AndroidElement header;
#AndroidFindBy(id= "android:id/title")
List<AndroidElement> titles;
#AndroidFindBy(id= "android:id/summary")
List<AndroidElement> summaries;
public boolean pageLoaded() {
try{
(new WebDriverWait(driver, 20)).until(ExpectedConditions.visibilityOfElementLocated(header));
return header.isDisplayed();
}
catch(Exception e){
return false;
}
}
}
And you must define your desiredCapabilities like following:
public static AppiumDriver<MobileElement> driver;
public static AppiumDriver<MobileElement> setupDesiredCapabilities(String appPackage, String appActivity,
String udid, String platformVersion, boolean noReset) {
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability("deviceName", "Android phone"); //any name
caps.setCapability("udid", udid);
caps.setCapability("platformName", "Android");
caps.setCapability("platformVersion", platformVersion);
caps.setCapability("appPackage", appPackage);
caps.setCapability("appActivity", appActivity);
caps.setCapability("noReset", noReset); //optional
try {
driver = new AndroidDriver<MobileElement>(new URL(
"http://127.0.0.1:4723/wd/hub"), caps);
} catch (MalformedURLException e) {
//
} catch (Exception ex) {
//
}
return driver;
}
Make sure you have define static AppiumDriver and use the same
driver object to call constructor of each page.
I am trying to write a script that fetches Estonian zip codes. Here is the code:
import com.gargoylesoftware.htmlunit.BrowserVersion
import org.openqa.selenium.{By, WebDriver}
import org.openqa.selenium.htmlunit.HtmlUnitDriver
object Application {
def main(args: Array[String]) {
val driver = new HtmlUnitDriver(BrowserVersion.CHROME)
driver.setJavascriptEnabled(true)
query(driver, "Pelguranna 9")
}
def query(driver: WebDriver, query: String) {
driver.get("https://www.omniva.ee/eng")
val tab = driver.findElement(By.xpath("//*[#class='search-tabs']/li[1]"))
tab.click()
val name = driver.findElement(By.name("zip_address"))
name.sendKeys(query)
name.submit()
val result = driver.findElement(By.xpath("//*[#id='zip_container']/p[0]"))
print(result)
}
}
Basically, you should go to URL, click on 'FIND A ZIP CODE' tab, insert address, press enter and take first result.
But I am getting an error:
Driver info: driver.version: unknown
at org.openqa.selenium.htmlunit.HtmlUnitWebElement.verifyCanInteractWithElement(HtmlUnitWebElement.java:282)
at org.openqa.selenium.htmlunit.HtmlUnitWebElement.sendKeys(HtmlUnitWebElement.java:326)
at Application$.query(grab.scala:20)
at Application$.main(grab.scala:10)
at Application.main(grab.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
I have never written anything like this before, so do not know what this error means. Can anyone say what is the problem with my code?
I found the following issues with your code.
The XPaths for elements are wrong.
There is not enough wait time between operations.
I am a JAVA guy and was able to get the zip code using the following code. I believe you can make the changes to python.
public static void main(String[] args) throws InterruptedException {
WebDriver driver = new HtmlUnitDriver(BrowserVersion.CHROME);
((HtmlUnitDriver) driver).setJavascriptEnabled(true);
test(driver, "Pelguranna 9");
}
public static void test(WebDriver driver, String query) throws InterruptedException {
driver.get("https://www.omniva.ee/eng");
Thread.sleep(5000);
WebElement tab = driver.findElement(By.xpath("//a[.='Find a ZIP code'][#href='#search-zip']"));
tab.click();
WebElement name = driver.findElement(By.name("zip_address"));
name.sendKeys(query);
name.submit();
Thread.sleep(10000);
WebElement result = driver.findElement(By.xpath("//*[#id='zip_container']/p/span"));
System.out.println(result.getText());
}
Hope this helps you.