Java - Selenium Firefox Driver - cannot click on link in iframe - java

Any help would be much appreciated.
I want my program to log into indeed.ca (this is working, as long as you enter correct user credentials), navigate to a specific job posting(working), click on the first orange apply button(working), an iframe pops up.
Then I want to click on the blue apply button in iframe that appears. "apply with a different resume?" link (if you are not logged in with indeed you won't see this.)
If you don't have an indeed account, and want to help, just try to click on any link in the pop-up iframe. Example: try to click "Create one now" link
The below code worked 2 weeks ago, but now it seems Indeed.ca made a minor change to site and code is broken
import java.io.IOException;
import java.util.ArrayList;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Test {
//IOException, InterruptedException, NoSuchElementException
public static void main(String[] args) throws IOException, InterruptedException, NoSuchElementException {
System.setProperty("webdriver.gecko.driver", "C:\\Users\\Padoga\\Documents\\geckodriver-v0.18.0-win64\\geckodriver.exe");
try {
FirefoxDriver driver = new FirefoxDriver();
driver.get("https://secure.indeed.com/account/login?service=my&hl=en_CA&co=CA");
driver.findElement(By.xpath("//*[#id=\"signin_email\"]")).sendKeys("youremail#email.com");
driver.findElement(By.xpath("//*[#id=\"signin_password\"]")).sendKeys("password");
driver.findElement(By.xpath("//*[#id=\"loginform\"]/button")).click();
driver.navigate().to("https://ca.indeed.com/viewjob?jk=ff97666702741fef&q=marketing&l=Toronto%2C+ON&tk=1boluh7om5igq9ng&from=web");
// int size = driver.findElements(By.tagName("iframe")).size();
// System.out.println(size);
Thread.sleep(3000);
//click orange "apply now" button
driver.findElement(By.xpath("//*[#id=\"apply-state-picker-container\"]/div[1]/span[1]")).click();
Thread.sleep(3000);
//don't believe this is working now - below used to switch to correct pop-up iframe
driver.switchTo().frame(1);
driver.switchTo().frame(0);
//not working anymore -- click "apply with a different resume?" link
driver.findElement(By.xpath("\"//*[#id=\\\"form_container\\\"]/div[2]/div[1]/div[1]/p/a\"")).click();
//no longer reach below steps
//click on resume "choose file" button and upload resume
driver.findElement(By.id("resume")).sendKeys("C:\\Users\\Padoga\\resumes\\Resume.pdf");
//click blue apply button
driver.findElement(By.id("apply-div")).click();
}
catch(Exception e){
//System.out.println(e.getMessage());
}
// driver.quit();
}
}

You need to switch first to perform any action inside iframe elements
The code to switch to element is :-
driver.switchTo().frame(0);
In above code 0 is a index. so it will swicth control to first iframe present in your DOM. You may need to change the index 1,2,.. so on . There another paramenetrs also to switch to frame without index
Basically, we can switch over the elements in frames using 3 ways.
By Index
By Name
Id By Web Element
Refer below URL for more information
http://toolsqa.com/selenium-webdriver/handling-iframes-using-selenium-webdriver/
https://www.guru99.com/handling-iframes-selenium.html
Hope it will help you :)

Try using below code and lets see if it works for you-
driver.switchTo().frame("page_frame");
driver.findElement(By.xpath("//*[#id="form_container"]/div[2]/div[1]/div[1]/p/a")).click();
update-
driver.switchTo().frame("indeedapply-modal-preload-iframe");
driver.findElement(By.xpath("//*[#id="form_container"]/div[2]/div[1]/div[1]/p/a")).click();
update 2-
I found an iframe inside another iframe. So, first you need to switch to the outer iframe then to inner iframe and then to the element.
Possible solutions-
driver.switchTo().frame("indeedapply-modal-preload-iframe");
driver.switchTo().frame(0);
driver.findElement(By.xpath("//*[#id="form_container"]/div[2]/div[1]/div[1]/p/a")).click();
OR
driver.switchTo().frame(0);
driver.switchTo().frame(0);
driver.findElement(By.xpath("//*[#id="form_container"]/div[2]/div[1]/div[1]/p/a")).click();

Related

Selenium Webdriver: How to bypass Google "accept-cookies" dialog box

I have a really simple Selenium WebDriver project in Java where I am using FireFox driver.
My goal is to navigate to Google's page (https://www.google.com) and when prompted to accept
Cookies be able to click on the "I agree"-button to just get rid of it and continue the automation process further. But for some reason I just can't get the browser to locate it.
This is the instruction I am using currently:
package main;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class SeleniumGoogleTest {
public static void main(String[] args) {
WebDriver driver = new FirefoxDriver();
driver.get("https://www.google.com");
WebElement acceptButton = driver.findElement
(By.xpath("/html/body/div/c-wiz/div[2]/div/div/div/div/div[2]/form/div/div[2]"));
}
}
I don't know why the browser can't locate it and activate/enable that part of the page
with neither Implicit wait or Explicit wait. Thread.sleep() method don't seem to be the
solution either in this case.
The only error message I get when running the application is that of "Unable to locate the element".
Is it that you actually can't automate some stuff with Selenium WebDriver or have I misunderstood some important concepts here?
Much grateful for all tips !
you can handle it by update the cookies "CONSENT" delete the old one because the value is "PENDING" and Add it with the below value.
driverManager.driver.manage().deleteCookieNamed ("CONSENT");
driverManager.driver.manage().addCookie(new Cookie("CONSENT","YES+shp.gws-"+LocalDate.now().toString().replace("-","")+"-0-RC2.en+FX+374"));
driverManager.driver.navigate().refresh();
The popup is located on an iFrame, first you have to switch to the iFrame:
driver.switchTo().frame(yourFrame);
after you can find the accept button, and click it:
driver.findElement(By.id("id")).click();
I've used the same solution as Jus, but Chrome had 'I agree' button id changed since then
Here how updated solution should look like
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import time
driver = webdriver.Chrome('chromedriver.exe')
driver.get('https://google.com/xhtml')
time.sleep(2) # seconds until popup appears
try: # 2 different popups
frame = driver.find_element_by_xpath('//*[#id="cnsw"]/iframe') #<-locating chrome cookies consent frame
driver.switch_to.frame(frame)
driver.find_element_by_xpath('//*[#id="introAgreeButton"]').click()#<-looking for introAgreeButton button, but seems google has changed its name since and it only works in old chrome versions.
except NoSuchElementException:
driver.find_element_by_xpath('//*[#id="L2AGLb"]').click() #<- pay attention to new id.
In case if this id will expire, I recommend you to inspect element yourself like this:
Inspect Element
Click twice 'Inspect element'
Locating 'I agree' button's id
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import time
driver = webdriver.Chrome('chromedriver.exe')
driver.get('https://google.com/xhtml')
time.sleep(2) # seconds until popup appears
try: # 2 different popups
frame = driver.find_element_by_xpath('//*[#id="cnsw"]/iframe')
driver.switch_to.frame(frame)
driver.find_element_by_xpath('//*[#id="introAgreeButton"]').click()
except NoSuchElementException:
driver.find_element_by_xpath('//*[#id="zV9nZe"]').click()

Trouble with Selenium, Java, Screenshots and clicking buttons

This is another question about Selenium and clicking. I have been struggling for about two days and can't get it to work - I have tried the answers in the internet and now I need a concerted effort. Thanks in Advance!!
I am working on the following site http://144.76.109.38/peTEST - this might help if you want to retrace my steps.
I am trying to fill out the login form, and then click on Login and see the answer page.
Here is my code:
import java.io.File;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.Writer;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.Select;
public class toJava {
public static void main(String[] args) {
System.setProperty("webdriver.gecko.driver","/home/tallen/RTI/lib/geckodriver/geckodriver");
WebDriver driver = new FirefoxDriver();
driver.get("http:144.76.109.38/peTEST");
File SF2 = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
try{
FileUtils.copyFile(SF2, new File("./out-004.png"));
}catch(IOException ioe){
System.out.println("There was an IO error");
}
driver.findElement(By.id("user_login_name")).click();
WebElement WE4 = driver.findElement(By.id("user_login_name"));
WE4.sendKeys("Superuser");
driver.findElement(By.id("user_password")).click();
WebElement WE6 = driver.findElement(By.id("user_password"));
WE6.sendKeys("Jkerouac1!");
WebElement WE7 = driver.findElement(By.xpath(".//*[#type='button'][#onclick='login()'][#value='Login']"));
WE7.sendKeys(Keys.ENTER);
File SF8 = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
try{
FileUtils.copyFile(SF8, new File("./out-005.png"));
}catch(IOException ioe){
System.out.println("There was an IO error");
}
driver.quit();
}
}
So basically I am opening up the page, taking a screenshot entering the user name and password, clicking Login and then taking another screenshot.
The compile and the run on this are clean - that is no exceptions and no problems. I even get two screenshots. The first screenshot shows the login page - with no data entered. The second screenshot shows the login page filled, the button I want to click marked, but not the "welcome Page" that you would get if you successfully log in. That the screenshot shows the button marked, I know that I have found the element. I have give the login info in the script, in case you want to try it out with Selenium first.
Why is the login button not being "clicked." I have tried click, perform, etc. to no avail. I have even tried putting in implicit waits - still nothing.
I have tried to Advanced Usage Interactions - and still nothing.
I am pretty new to Selenium and Java and am hoping that it is just something stupid that I am overlooking. But after looking through the Web, the solutions there are just not helping.
I am working on Debian-70-Wheezy-64-LAMP
My Selenium Libraries are from client-combined-3.0.1-nodeps.jar
My Geckodriver is v0.11.1-linux64
Thanks for the Help!!!
Hi, I don't know if it can cause a problem but anyway for the login button I would use WE7.click(); I just think that it's easier to understand what you're trying to do with the element.
I've been working with the GeckoDriver for a while and talking with some experienced people in the area and they told me that Gecko has many problems that are not fixed yet.
They always recommended me not to use GeckoDriver because it seems to fail very often and told me to use FirefoxDriver instead.
To try it this way, and this is important, you'll just need to keep working with an older version of Firefox as the version 46 that is compatible with FirefoxDriver (that version worked for me and you can download it from places like this) and avoid using GeckoDriver.
Also the version 47 seems to work with the FirefoxDriver as I've found here.
Remember: When you install one of these previous versions of Firefox, don't forget to go to settings and disable the automatic updates and background updates because if you don't do this, you'll end soon again with the latest version that requires GeckoDriver.
In addition you can try some validation as the following:
if(WE7.isDisplayed() && WE7.isEnabled()){
WE7.click();
}
This kind of validations would help in case that the page isn't fully loaded at the moment that you're trying to take action over the web element. If the element is not ready, you will click it without errors but it just won't work
Hope this works for you too!

How to close Popovers and in-line ads with selenium webdriver

I'm trying to learn Selenium Webdriver using tutorials online etc...
I'm struggling to overcome this obctacle which is to close this popover.
Using:
Laptop: Alienware
O.S: Windows 10 64bits
Browser: Firefox 51.0.1 (32-bit)
Eclipse: Version: Neon.2 Release (4.6.2) Build id: 20161208-0600
Selenium Webdriver: Java 3.0.1 2016-10-18
`package com.indeed.tests;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class IndeedJobSearch {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
//Create firefox driver to drive the browser
System.setProperty("webdriver.gecko.driver", "C:\\Users......\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
//Open Indeed home page
driver.get("https://www.indeed.co.uk/");
//Find what field and enter Selenium
Thread.sleep(1000);
driver.findElement(By.id("what")).sendKeys("Selenium");
//Find location field and enter London
driver.findElement(By.id("where")).clear();
Thread.sleep(1000);
driver.findElement(By.id("where")).sendKeys("London");
//Find FindJobs button and click on it
Thread.sleep(1000);
driver.findElement(By.id("fj")).click();
//Close popup - popover, not popup
//prime-popover-div
//selenium webdriver cannot close bootstrap popovers
//Can't find a solution
//From job search results page, get page title and jobs count message
//searchCount
System.out.println(driver.getTitle());
System.out.println(driver.findElement(By.id("searchCount")).getText());
driver.close();
}
}
`
Expected Result: Selenium Webdriver would open firefox browser, load indeed.co.uk webpage, insert "Selenium" in the first field, insert "London" in the second field, hit the search button, get title and job count values on the console and driver window.
Actual Result: Selenium Webdriver would open firefox browser, load indeed.co.uk webpage, insert "Selenium" in the first field, insert "London" in the second field, hit the search button, STOPS the focus in on the url field and nothing else happens.
I've tried a few solutions but couldn't get it working
(https://sqa.stackexchange.com/questions/5310/how-to-close-pop-up-window-in-selenium-webdriver)
e.g.
driver.findElement(By.id("prime-popover-close-button")).click();
Driver.SwitchTo().frame("prime-popover-div");
Driver.findElement(By.id("prime-popover-close-button")).click();
Driver.SwitchTo().defaultContent();
driver.findElement(By.xpath("//*[#id='prime-popover-close-button']/a/img")).click();
Note: Not entirely sure my xpath was writen correctly, still learning.
None of these seem to work. I read something about Selenium WebDriver not handling bootstrap popovers, not sure if that's exactly my case, or if any of you has found a solution.
Would love solutions and or advice :)
Thank you very much in Advance.
Your code generally looks fine (other than the use of Thread.Sleep(), which I will address in a minute.
Basically what you want to do in these cases is to right-click on the close X of the dialog and treat it like any other element on the page. Find a locator for the X, in this case it also has an id, prime-popover-close-button, that we can use. All you need to do is grab that element using the id and click it to dismiss the popup. I've simplified the code below.
driver.get("https://www.indeed.co.uk/");
driver.findElement(By.id("what")).sendKeys("Selenium");
driver.findElement(By.id("where")).sendKeys("London");
driver.findElement(By.id("fj")).click();
driver.findElement(By.id("prime-popover-close-button")).click();
If you aren't trying to test the UI (entering text and clicking buttons) on the search page, you can just navigate directly to the url and even feed your own keywords in, if you like. See the code below for that.
String what = "selenium";
String where = "london";
driver.get("https://www.indeed.co.uk/jobs?q=" + what + "&l=" + where);
driver.findElement(By.id("prime-popover-close-button")).click();
Now back to Thread.Sleep(). This form of wait is generally a bad practice. You can do some research into the details but suffice it to say that it's not flexible. If you sleep for 10s and the element is present in 25ms, you've waited a long time that you didn't need to. Read up on WebDriverWait and ExpectedConditions. While you didn't need it here, you will eventually need to wait and these are best practices for waiting.
It looks like I'm doing the same tutorial you are :) I ran into the exact same issue you did, and tried almost everything you did to click that close button and kill that popover before finding this thread.
It appears that the problem lies in that the popover isn't immediately available for Selenium to close after we click Find Jobs. A 'wait.until..' has to be set in place to wait for the popover to appear so we can close it. Here's what I did:
package com.indeed.tests;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait; //**and this
public class IndeedJobSearch {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
//Create firefox driver to drive the browser
WebDriver driver;
System.setProperty("webdriver.gecko.driver", "C:\\Users\\BURRITOBEAST\\Downloads\\jars\\geckodriver-v0.14.0-win64\\geckodriver.exe");
driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver,10); //**and this. 10 is the number of seconds it'll wait before an error is thrown.
//Open Indeed homepage
driver.get("http://www.indeed.com");
//Find the 'what' field and enter "selenium"
driver.findElement(By.id("what")).sendKeys("Selenium");
//Find the 'location' field and enter "San Diego, CA"
driver.findElement(By.id("where")).clear();
driver.findElement(By.id("where")).sendKeys("San Diego, CA");
//Find the 'findjobs' button and click on it
driver.findElement(By.id("fj")).click();
wait.until(ExpectedConditions.elementToBeClickable(By.id("prime-popover-close-button"))); //**this is where the magic happens
//Thread.sleep(1000); **tested my idea first using a sleep. then found the wait method after. plus, i want to avoid sleeps if possible to make things speedy.
driver.findElement(By.id("prime-popover-close-button")).click();
//From the job search results page, get page title and jobs count msg
}
}

Getting error NoSuchElementException: Unable to locate element: in "big.findElement(By.xpath("//*[#id='rso']/div[1]/div/div/h3/a")).click();"

package FlipPkg;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class BigBasket {
public static void main(String[] args) {
System.setProperty("webdriver.gecko.driver","C:\\Users\\NP031997\\Downloads\\geckodriver-v0.12.0-win64\\geckodriver.exe");
WebDriver big = new FirefoxDriver();
big.get("https://www.google.com/");
big.manage().window().maximize();
System.out.println("The webpage is:" + big.getTitle());
big.findElement(By.xpath(".//*[#id='gs_htif0']")).sendKeys("Big Basket");
big.findElement(By.xpath(".//*[#id='gs_htif0']")).sendKeys(Keys.ENTER);
big.findElement(By.xpath("//*[#id='rso']/div[1]/div/div/h3/a")).click();
System.out.println("The current webpage is:" + big.getTitle());
}
}
the code is failing at position
big.findElement(By.xpath("//*[#id='rso']/div[1]/div/div/h3/a")).click();
Your code is fine.The WebDriver will find that element for sure, but you have a small problem in that code. There might be two reasons for NoSuchElementException:
The WebDriver won't take any delay for finding the link that you are finding with your code. The WebDriver will not wait for the search results page to load, so you will get NoSuchElementException.
The link's xpath may vary dynamically because google will retrieve dynamic search results.
The solutions for this are as follows:
You have to use waits after the 'enter' functionality.
You can use waits or waitForPageToLoad() function. The following code is for WebDriverWait.
WebDriverWait wait = new WebDriverWait(big,120);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[#id='rso']/div[1]/div/div/h3/a"));
You can use this for clicking the element by
WebDriverWait wait = new WebDriverWait(big, 15);
wait.until(ExpectedConditions.elementToBeClickable(By.partialLinkText("Big Basket")));
You can also use Contains() function for finding the XPath of the element:
//a[contains(text(),’Big Basket’)]
By using 2nd and 3rd method you will get a list of elements because many elements contains the Text Big Basket.

Downloading a pdf file

I am automating a application using selenium webdriver,below is my codes which works fine
enter code here:
import java. util.concurrent. TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.JavascriptExecutor;
import com.thoughtworks.selenium.SeleneseTestCase;
public class MonTaxRep1 extends SeleneseTestCase{
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
WebDriver driver = new FirefoxDriver();
driver.get(" URL ");
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
WebElement un= driver.findElement(By.name("username"));
un.sendKeys("clientremote");
driver.findElement(By.name("password")).sendKeys("12345678");
driver.findElement(By.name("submit")).click();
// find the element and click on signin
// driver.findElement(By.id("loginButton")).click();
driver.findElement(By.xpath("//a/span[contains(text(),'Thailand')]")).click();
driver.findElement(By.linkText("Williams Limited Thailand")).click();
driver.findElement(By.xpath("//map[#id='Map']/area[3]")).click();
driver.findElement(By.cssSelector("a > img")).click();
driver.findElement(By.xpath("//img[#onclick=\"showItem('_self')\"]")).click();
new Select(driver.findElement(By.name("pay_year"))).selectByVisibleText("2010");
new Select(driver.findElement(By.name("pay_month"))).selectByVisibleText("January");
driver.findElement(By.linkText("Monthly Tax Report")).click();
driver.findElement(By.name("g_title")).sendKeys("Test1");
driver.findElement(By.xpath("//input[#value='Download']")).click();
When selenium clicks on download link a pop-up window appears which contains two radio buttons by default the radio button is clicked on for open with option now i need to switch that radio button into save as option and click on OK button .
When i click on OK button the the pdf file should be saved in some specific local drives .
For this i have used the below code but it is not working.
//Before opening pop-up get the main window handle
String mainWindowHandle=driver.getWindowHandle();
//open the pop-up window(i.e click on element which causes open a new window)
driver.findElement(By.xpath("//input[#value='Download']")).click();
//Below code returns all window handles as set
Set s = driver.getWindowHandles();
Iterator ite = s.iterator();
while(ite.hasNext())
{
String popupHandle=ite.next().toString();
if(!popupHandle.contains(mainWindowHandle))
{
driver.switchTo().window(popupHandle);
}
So please help me in providing code for this,
I had a doubt whether the downloaded pdf file can be opened and read line by line and can compare some text present in that or not,is this possible ??
The short answer: This has been asked many times, please search.
The long and more correct answer: As of now (2012/11), it can't be done via WebDriver. It's one of the most requested features for the Selenium project. You can try one of these things:
Make a request for the specified link using HttpURLConnection or Apache HttpComponents. You can even download the file this way, although the usual practice is just to assert a 200 OK response to make sure that the file can be downloaded (since you usually don't really need the file when you're testing your application).
Snatch the file using any Java approach. Or this tool made by someone to be used with Selenium.
Use the Robot class to simply press Down arrow and Enter or something. But beware, this will only work for your particular browser and OS. It will break on any other configuration.
In firefox you can fix this by adding the following code to the setUp method of your selenium tests.
profile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/pdf,application/x-pdf");
If you have other types of documents you want to download other than pdfs you should look up the MIME type of whatever document you are trying to download and adding it to the comma delimited list.

Categories