selenium executeScript hangs on IE - java

OK folks, I've searched the web for 2 days to solve the modal dialog problem. Great information out there and it all works except for IE. I'm trying to open a file upload dialog and select a new file. I created autoIT scripts and they work just fine with FF and Chrome. When I try with IE the "executeScript" does not return back to my test scripts. In IE the "file upload" dialog is opened. But That is where my scripts stops. If I manually run the autoIT script, it returns back to the test script after the "file upload" dialog closes.
//WebDriver driver = new FirefoxDriver();
// processPage(driver);
WebDriver ieDriver =new InternetExplorerDriver();
processPage(ieDriver);
// WebDriver chromeDriver = new ChromeDriver();
// processPage(chromeDriver);
.
.
. other code
.
.
WebElement element = driver.findElement(By.name(uploadDifferntFile));
if (driver instanceof InternetExplorerDriver) {
((InternetExplorerDriver) driver).executeScript("arguments[0].click();", element);
} else if(driver instanceof FirefoxDriver){
((FirefoxDriver) driver).executeScript("arguments[0].click();", element);
} else if(driver instanceof ChromeDriver){
((ChromeDriver) driver).executeScript("arguments[0].click();", element);
}
.
.
. autoIT
.
.
.
try {
Process proc = Runtime.getRuntime().exec(fileToExecute);
} catch (IOException e) {
System.out.println("Failed to execute autoIT");
e.printStackTrace();
}
Thank you for all your support

It seems to be related to modal dialog invoked during your argument[0].click operation in IE, see https://code.google.com/p/selenium/wiki/InternetExplorerDriver, section "Clicking Elements or Submitting Forms and alert()", I think it describes same issue.
Few options to try would be:
Replace your with JavaScript code with just "element.click()" or
"element.sendKeys(Keys.ENTER)"
Start a new thread before you do
argument[0].click, wait in that thread a bit and then run autoIt
code
Also you can replace your existing code with JavascriptExecutor to write JavaSrcipt only once:
WebElement element = driver.findElement(By.name(uploadDifferntFile));
if (driver instanceof JavascriptExecutor) {
((JavascriptExecutor) driver).executeScript("arguments[0].click();", element);
}

I've just stepped in the same problem, because sendKeys wasn't a stable solution for me working with Internet Explorer. So I build a variation with AutoIt.
For Firefox I use the JavaScript and for IE I do a doubleclick on the input field:
// fileInput is the WebElement resulting from the input field with type file
if (browser == "FF") {
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", fileInput);
} else {
Actions action = new Actions(driver);
Action doubleClick = action.doubleClick(fileInput).build();
doubleClick.perform();
}

Related

Block advertisements on Selenium

I'm currently using Selenium for one of my academic assignments regarding quality assurance automation. For this, I'm using a website that is not handled by me or anyone I know.
I have noticed that when I run my test cases, sometimes, advertisements appear on the website in the Chrome window that opens up. Since it is not a pop-up, using disable-popup-blocking does not work. Moreover, since the advertisement doesn't always appear, using a code segment to close the advertisement modal doesn't work either.
The following image depicts an example scenario.
Is there a workaround for this issue? Thank you in advance!
#Test
#Order(2)
public void CovertLang() throws InterruptedException {
// Navigating to 123apps.com website
driver.get("https://123apps.com/");
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
// Accessing the language modal
WebElement langButton = driver.findElement(By.id("language-link"));
langButton.click();
// Wait until the modal opens
wait.until(ExpectedConditions
.visibilityOfElementLocated(By.className("modal-title")));
// Selecting German as the language
WebElement deutschButton = driver.findElement(By.xpath("//a[#href='/de/']"));
deutschButton.click();
Thread.sleep(1000);
// Comparing the web URL
String newURL = driver.getCurrentUrl();
assertEquals("https://123apps.com/de/", newURL);
}
The above shows an example of a test I conducted.
You can disable that ad using the below js code:
// Selecting German as the language
WebElement deutschButton = driver.findElement(By.xpath("//a[#href='/de/']"));
deutschButton.click();
Thread.sleep(1000);
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("const elements = document.getElementsByClassName('adsbygoogle adsbygoogle-noablate'); while (elements.length > 0) elements[0].remove()");
deutschButton.click();
// Comparing the web URL
String newURL = driver.getCurrentUrl();
assertEquals("https://123apps.com/de/", newURL);

Unable To Click Paypal Button Continue With Selenium

My code begins by signing me into PayPal, then signing into eBay and navigating to the pay fees page, then checking out with PayPal. The final "Continue" button I can't click/submit. I've tried by xpath, id and class. I even tried sending TAB 7x until the Continue button and then sending Enter but that didn't work.
I have found this discussion but I'm not sure how to make it work for me.
PayPal Sandbox checkout 'continue button' - Unable to locate element: - C# WebDriver
Here's a screenshot of the PayPal code and page I'm trying to do.
//Chrome WebDriver specific
System.setProperty("webdriver.chrome.driver", "C:\\automation\\drivers\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize(); //maximise webpage
WebDriverWait wait = new WebDriverWait(driver, 20);
//navigate to Paypal
driver.get("https://www.paypal.com/uk/signin");
//wait 2.5s for the page to load
try {
Thread.sleep(2500);
}
catch (Exception e) {
e.printStackTrace();
}
WebElement paypalEmail = driver.findElement(By.id("email"));
paypalEmail.sendKeys("******");
//wait 2.5s for the page to load
try {
Thread.sleep(2500);
}
catch (Exception e) {
e.printStackTrace();
}
WebElement paypalSubmit = driver.findElement(By.id("btnNext"));
paypalSubmit.click();
String URL = ("https://www.paypal.com/uk/signin");
driver.get(URL);
WebElement form2 = driver.findElement(By.cssSelector(".main form"));
WebElement username = form2.findElement(By.id("password"));
username.sendKeys("******");
WebElement paypalSubmit2 = driver.findElement(By.id("btnLogin"));
paypalSubmit2.click();
//navigate to Ebay
driver.get("https://signin.ebay.co.uk/ws/eBayISAPI.dll?SignIn&ru=https%3A%2F%2Fwww.ebay.com%2F");
// Enter user name , password and click on Signin button
WebElement form = wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#mainCnt #SignInForm")));
form.findElement(By.cssSelector("input[type=text][placeholder='Email or username']")).sendKeys("******");
form.findElement(By.cssSelector("input[type=password]")).sendKeys("******");
form.findElement(By.id("sgnBt")).click();
driver.get("http://cgi3.ebay.co.uk/ws/eBayISAPI.dll?OneTimePayPalPayment");
//WebElement Pay =
driver.findElement(By.xpath("//input[#value='Pay']")).click();
WebDriverWait wait2 = new WebDriverWait(driver, 15);
wait2.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[#id=\"confirmButtonTop\"]")));
driver.findElement(By.xpath("//*[contains(#id,'confirmButtonTop')]")).click();
}
}
Based on your given screenshot one of following should work to click on continue button :
Method 1 :
WebElement paypalSubmit = driver.findElement(By.xpath("//input[#data-test-id='continueButton']"));
paypalSubmit.click();
Method 2:
By paypalButton=By.xpath("//input[#data-test-id='continueButton']"));
WebElement element=driver.findElement(paypalButton);
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].scrollIntoView(true);",element);
js.executeScript("arguments[0].click();", element);
Try 2nd method if you feel your button require bit scroll to bottom to get clickable.
one more xpaths you can use for button if above don't work :
//input[#value='Continue' and #id='confirmButtonTop']
In my experience, paypal likes to use iFrames. If that's true in your case, that means unless you tell webdriver to switch frame contexts, that paypal form will be unavailable to you regardless of your xpath/css selectors.
You can get a list of all available frames currently loaded with this code:
String[] handles = driver.getWindowHandles()
Your actual page will always be the 0th index in that returned array. If paypal is your only iFrame, then you can target the 1th index. Here's a possible solution to that:
String mainPageHandle = handles[0];
String paypalHandle = handles[1];
driver.switchTo().window(paypalHandle);
// Do paypal interactions
driver.switchTo().window(mainPageHandle);
// Back to the main page
There are definitely more robust ways to handle this, and if your page unfortunately has more than one iFrame, then you may need to do more to verify which handle is which, such as test the presence of an element you know is contained within. In general, the frames will load in the same order every time. As a golden path to this problem, this will get you in and out of that iFrame to perform work.
Sometimes the conventional click() doesn't work. In that case, try using the Javascript Executor Click as below.
Make sure you import this class
org.openqa.selenium.JavascriptExecutor
And use this instead of click();
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", driver.findElement(By.xpath(“//input[#data-test-id='continueButton']”)));
Try this and let me know if this works for you.

Unable to click on multiple links on a webpage in selenium webdriver with java

My Code
WebDriver driver = new FirefoxDriver();
driver.get("https://google.com");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
driver.findElement(By.name("q")).sendKeys("selenium");
driver.findElement(By.xpath("//button[#value='Search']")).click();
List<WebElement> alllinks = driver.findElements(By.xpath("//div[3][#class='_NId']/div/div/div/h3"));
for(WebElement cl:alllinks)
{
System.out.println(cl.getText());
if(cl.getText()!="")
{
cl.click();
}
}
By above code i am not getting any exception but also i am not able to click on any link on a webpage, I just want to click on every link one by one.Please tell me the solution how to do this, Thanks in advance.
Your assumption of opening all links is correct but the code could not show you the desired output as
1> When google results are shown for 'Selenium' keyword, you have many links over there. So if you manually click on every link - it opens in the same tab by which the other links will not be accesible as WebDriver gives you org.openqa.selenium.StaleElementReferenceException:exception.
Now try this code :
open some driver
driver.get("https://google.com");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
driver.findElement(By.name("q")).sendKeys("selenium");
driver.findElement(By.xpath("//button[#value='Search']")).click();
List<WebElement> alllinks = driver.findElements(By.xpath("//div[3][#class='_NId']/div/div/div/h3"));
for(WebElement cl:alllinks)
{
System.out.println(cl.getText());
if(cl.getText()!="")
{
Actions action = new Actions(driver); // I have added these lines
action.keyDown(Keys.CONTROL).moveToElement(cl).click().perform();
action.keyUp(Keys.CONTROL).perform();
}
}
So now all links will be opened in a new tab and it works .

Phantomjs' selenium Ajax code not loaded

I just discovered Selenium and I'm trying to learn how to use it with PhantomJS. The first example I've found was about getting a list of links from booking.com.
I tried running it with PhantomJS without luck. Firefox runs it well. The code in java looks like this:
private void start() {
Capabilities caps = new DesiredCapabilities();
((DesiredCapabilities) caps).setJavascriptEnabled(true);
((DesiredCapabilities) caps).setCapability("takesScreenshot", true);
((DesiredCapabilities) caps).setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, "D:\\phantomjs-2.0.0-windows\\bin\\phantomjs.exe");
//WebDriver driver = new PhantomJSDriver(caps);
WebDriver driver = new FirefoxDriver();
driver.get("http://www.booking.com");
driver.findElement(By.id("destination")).sendKeys("Berlin");
//saveSShot(driver, "sel1.png");
long timeOut = 5000;
long end = System.currentTimeMillis() + timeOut;
while (System.currentTimeMillis() < end) {
if (String.valueOf(
((JavascriptExecutor) driver)
.executeScript("return document.readyState"))
.equals("complete")) {
break;
}
}
//saveSShot(driver, "sel2.png");
try {
//writeFile(driver, "output1.txt");
new WebDriverWait(driver, 3).until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("ul.ui-autocomplete li a"))).click();
//writeFile(driver, "output2a.txt");
//saveSShot(driver, "sel3.png");
driver.findElement(By.name("idf")).click();
driver.findElement(By.className("b-searchbox-button")).submit();
List<WebElement> list = driver.findElements(By
.cssSelector("a.hotel_name_link"));
for (WebElement webElement : list) {
System.out.println(webElement.getText());
}
} catch (TimeoutException e) {
System.out.println(e.toString());
//writeFile(driver, "output.txt");
}
}
Note the two declarations of driver. If I use Firefox, the WebDriverWait works. On PhantomJS it gives an error with WebDriverWait (Element not found :262 in error)
I have added all code. You can paste it in a new project, add the class and includes and you'll see how it (not) work. The two commented method saveSShot and writeFile must be written. I used them for debugging purposes. What I see on the second screenshot is that "Berlin" is in fact written, but the ajax dropdown isn't there. With Firefox it appears.
This has nothing to do with ghostDriver: this is a generic WebDriver usage case. You need to define such a scenario yourself, most probably by registering some JS in the page to do the check for you, and use the driver to pick up the result. You should provide a mechanism that waits for this element to be displayed and enabled. Waiting for the page's ready-state. Such simple solution can do the trick:
long timeOut = 5000;
long end = System.currentTimeMillis() + timeOut;
while (System.currentTimeMillis() < end) {
if (String.valueOf(
((JavascriptExecutor) driver)
.executeScript("return document.readyState"))
.equals("complete")) {
break;
}
}
I've used the ghostDriver for rich content (gaming sites) and it worked pretty well with all the AJAX.
I did some research and this is what I find working too:
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
wait.Until(d => (bool)(d as IJavaScriptExecutor).ExecuteScript("return jQuery.active == 0"));
Here is an article that can help you if you decide to proceed with the JS code.

Selenium webdriver :org.openqa.selenium.InvalidElementStateException: Element is disabled and so may not be used for actions

I am getting this error while trying to write to simple code in selenium webdriver to enter a value in google search page and enter.
Following is my code -:
WebDriver driver = new FirefoxDriver(profile);
driver.manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
driver.get("http://www.google.com");
WebElement element=driver.findElement(By.xpath("//input[#id='gs_htif0']"));
boolean b = element.isEnabled();
if (b){
System.out.println("Enabled");
}
element.sendKeys("Test Automation");
element.submit();
Can anyone please help me out with this? How to enable a disabled element?
You are using the wrong 'input' for entering the text. You should be using the following XPath:
//input[#name='q']
Like
WebElement element=driver.findElement(By.xpath("//input[#name='q']"));
This 'input' element accepts the input text just fine.
You can try to run javascript on page:
((JavascriptExecutor) driver).executeScript("document.getElementById('gs_htif0').disabled = false");
or
((JavascriptExecutor) driver).executeScript("arguments[0].disabled = false", element);
See, if this might help,
WebDriver driver = new FirefoxDriver(profile);
driver.manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
driver.get("http://www.google.com");
WebElement element = driver.findElement(By.name("q"));
if(element.isEnabled()) {
System.out.println("Enabled");
element.sendKeys("Test Automation");
element.submit();
}
Try this:
WebDriverWait wait = new WebDriverWait(driver, 40);
driver.get("http://www.google.com");
wait.until(ExpectedConditions.visibilityOfElementLocated(By
.xpath("//input[#id='gs_htif0']")));
driver.findElement(By.xpath("//input[#id='gs_htif0']"))
.sendKeys("Test Automation" + Keys.ENTER);
Or:
public boolean isElementPresent(WebDriver driver, By by)
{
try {
driver.findElement(by);
System.out.print("Enabled");
return true;
} catch (NoSuchElementException ignored) {
return false;
}
}
isElementPresent = isElementPresent(
driver, By.xpath("//input[#id='gs_htif0']"));
if (isElementPresent) {
element.sendKeys("Test Automation");
element.submit();
}
Or change xPath to name selector.
If i am correct then you are using the firebug add-on in the firefox driver to get the path for the searchbox. But the firebug seems to provide a path where the Id for the searchbox is not correct. If you use the inspect element option you can see the difference (in the below image you can spot the difference yourself).

Categories