I used below code for finding the element in the frame but I got the error
kindly explain by this framebyinedex, framebystring, framebywebelement:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class Framebyindex
{
public static void main(String[] args)
{
WebDriver f1=new FirefoxDriver();
f1.get("http://spicareers.com/spicareers/");
f1.switchTo().frame(1);
f1.findElement(By.linkText(" .Net - Senior Developer ")).click();
}
}
The error is:
Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"link text","selector":" .Net - Senior Developer "}
Before you have to switch to the frame:
driver.get("http://spicareers.com/spicareers/");
WebElement frame= driver.findElement(By.xpath("//frame[#name='JRAMPSMainFrame']"));
driver.switchTo().frame(frame);
and after you could try with:
WebElement myEl= driver.findElement(By.xpath("//*[contains(text(), ' .Net - Senior Developer ')]"));
myEl.click();
Finally, if you want to switch back:
driver.switchTo().defaultContent();
EDIT
The interested element is inside the iframe with name "JRAMPSMainFrame". If you inspect your html, you could notice this:
NoSuchElementException simply means that, the selenium did not detect a link with the text as you asked it.
I suggest you to work with use by.xpath to resolve it. To get the xpath of the element, take the below steps on your chrome, or firefox browser.
Right click on the element (here the link)
Click on inspect. It opens the inspect console (Elements tab) in your browser, and highlights the clicked element.
Right click on the element in the elements tab
Choose copy
Copy Xpath
In your code, replace By.linkText with By.xpath
Paste the value as an string into the xpath("you paste here")
Or simpler, watch this video
Seems like you have selected a wrong frame or the link text might contain more spaces.
Chrome developer tools is your best friend in this situation. Use it to find the element correctly and to identify the frame.
SELECT FRAME
Open the application in chrome.
Open developer tools
Click Console tab of developer tool
Select you frame from the drop down
In the above picture there is only one frame.
FIND ELEMENT
After selecting the frame, type $x("//a[normalize-space(.) = '.Net - Senior Developer']") to check your xpath.
$x("") is the function for checking xpath in browser.
Using the above mechanism find the frame and the element.
Cheers!
If you take a closer look at the HTML of http://spicareers.com/spicareers/ the WebElement with text as .Net - Senior Developer is within an <iframe> tag. So before accessing the intended WebElement we have to switch to the frame first either through the frame_name, frame_id or frame_index as follows:
System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("http://spicareers.com/spicareers/");
driver.switchTo().frame("JRAMPSMainFrame"); //using "frame_name"
WebElement elem = driver.findElement(By.xpath("//*[contains(text(), ' .Net - Senior Developer ')]"));
elem.click();
You can use this code, First enter into the frame using name locator and try to locate the career option then
Try this code, I have modified your code:
public class Framebyindex
{
public static void main(String[] args)
{
WebDriver f1=new FirefoxDriver();
f1.get("http://spicareers.com/spicareers/");
f1.switchTo().frame( f1.findElement(By.name("JRAMPSMainFrame")));
WebElement netCareer= f1.findElement(By.xpath("//*[contains(text(), ' .Net - Senior Developer ')]"));
netCareer.click();
}
}
By using:
https://github.com/nick318/FindElementInFrames
you can write following:
SearchByFramesFactory searchFactory = new SearchByFramesFactory(driver);
SearchByFrames searchInFrame = searchFactory.search(() -> driver.findElement(By.xpath("//*[contains(text(), ' .Net - Senior Developer ')]")));
searchInFrame.getElem().ifPresent(WebElement::click);
Related
I am creating an automated test cases for this page https://cloud.google.com/products/calculator in scope of my practical task using Selenium + Java.
At some point I've faced with a problem when the WebDriver couldn't find an element inside the iframe, even if in the previous test case I was able to interact with the elements of this iframe.
All my test cases are running one by one without closing the driver and each next test case can passed only if the previous test case passed as well.
Here is my GitHub repo:
https://github.com/SerhiiVeselov/hurt-me-planty.git
Here are my test cases:
#BeforeAll
public static void driverSetup() {
driver = new ChromeDriver();
driver.manage().window().maximize();
mainPage = new MainPage(driver);
searchResultsPage = new SearchResultsPage(driver);
pricingCalculatorPage = new PricingCalculatorPage(driver);
fluentWait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(10))
.pollingEvery(Duration.ofSeconds(2))
.ignoring(NoSuchElementException.class);
}
#Test
#Order(1)
#DisplayName("Search of the Pricing Calculator page")
public void openPricingCalculator() {
mainPage.openPage();
fluentWait.until(ExpectedConditions.visibilityOf(mainPage.getCookiesOkBtn()));
mainPage.closeCookiesPopUp();
mainPage.openSearchField();
mainPage.enterSearchRequest();
fluentWait.until(ExpectedConditions.visibilityOf(mainPage.getSuggestSearchResult()));
mainPage.clickSuggestSearchResult();
fluentWait.until(ExpectedConditions.visibilityOf(searchResultsPage.getSearchResultsTab()));
searchResultsPage.clickPricingCalculatorLink();
assertEquals("https://cloud.google.com/products/calculator", driver.getCurrentUrl());
fluentWait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(pricingCalculatorPage.getCloudSideFrame()));
fluentWait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt((pricingCalculatorPage.getMyFrame())));
}
#Test
#Order(2)
#DisplayName("Fill the Calculation Form")
public void fillCalculationForm() {
pricingCalculatorPage.enterNumberOfInstances();
pricingCalculatorPage.selectOperatingSystem();
pricingCalculatorPage.selectProvisioningModel();
pricingCalculatorPage.selectMachineType();
pricingCalculatorPage.checkAddGpuCheckBox();
pricingCalculatorPage.selectGpuType();
pricingCalculatorPage.selectGpuQuantity();
pricingCalculatorPage.selectLocalSsd();
pricingCalculatorPage.selectDatacenterLocation();
pricingCalculatorPage.addToEstimate();
fluentWait.until(ExpectedConditions.visibilityOf(pricingCalculatorPage.getTotalEstimatedCost()));
assertEquals("Instance type: n1-standard-8", pricingCalculatorPage.getInstanceTypeTest().getText());
}
#Test
#Order(3)
#DisplayName("Check the name of the Machine type")
public void verifyMachineType() {
assertEquals("Instance type: n1-standard-8", pricingCalculatorPage.getInstanceTypeTest().getText());
}
Here is the webpage for which I've created 2d and 3d test cases: https://cloud.google.com/products/calculator
page for automation in 2d and 3d test cases
So far, 1st and 2d test cases are passing and working as expected. But 3d test case is failing all the time cause the WebDriver couldn't find the element from the getInstanceTypeTest method:
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//div[contains(text(), 'Instance type')]"}
Most of elements I interested in are located inside the same iframe (id=myFrame).
I have a selector for instanceTypeTest WebElement creared using xpath //div[contains(text(), 'Instance type')].
In 3d test case I want to check this field and get from it a text value to compare it with the value which was selected at the left form at https://cloud.google.com/products/calculator page.
I guess, after I filling the left form with data and clicking the 'ADD TO ESTIMATE' button something is happening with the iframes or the driver is loosing it's focus to the right frame.
I tried to add at the beginning of the 3d test case some code which should take driver back to the default web page content and then switch driver to outer iframe (cloudSideFrame) and after that - to inner iframe (myFrame):
driver.switchTo().defaultContent(); fluentWait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(pricingCalculatorPage.getCloudSideFrame())); fluentWait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt((pricingCalculatorPage.getMyFrame())));
It didn't help me. Driver still couldn't find Instance type field.
I can't understand why driver could find some elements inside the iframe even if it could find some others inside the same iframe.
Please help me to solve this problem.
websitepicture
Hi, Trying to find the selector for the element in the attached picture to click on it with selenium.
chrome cannot find it and chropath says:
"This element might be inside iframe from different src. Currently ChroPath doesn't support for them."
But I do not see any iframe or src.
enter image description here
public void switchIntoIframe(WebElement el) throws myInterviewProjectExceptions {
webDriver.switchTo().frame(el)
};
tried to pass the iframe:
#FindBy(xpath="//*[#id=\"root\"]")
private WebElement iframe;
to:
webDriver.switchTo().frame(el);
no help:
org.openqa.selenium.NoSuchFrameException: Unable to locate frame: c7bb48a5-9eb0-410c-9593-9517d57d1490
Could you please try with the new version of ChroPath 6.0 and you can try //a[#class='module-link media']
I am currently looking for a solution to click on Sava button in chrome print preview window with selenium Java.
Is there any way we can handel chrome print preview page?
I have tried with the Robot class, but it seems not reliable/stable for my application.
Could you please someone help me to achieve this with selenium Java.
I fail to see any "Save" button on print preview page for Chrome browser
Here is how you can click "Cancel" button, I believe you will be able to amend the code to match your requirements:
First of all make sure to wait for the preview page to be available using Explicit Wait
Change the context to the print preview window via WebDriver.switchTo() function
All the elements at the print preview page are hidden in ShadowDom therefore you will need to:
Locate the element which is the first parent of the element you're looking for
Get its ShadowRoot property and cast the result to a WebElement
Use the WebElement.findElement() function to locate the next parent
repeat above steps until you reach the desired button
Example code just in case:
new WebDriverWait(driver, 10).until(ExpectedConditions.numberOfWindowsToBe(2));
driver.switchTo().window(driver.getWindowHandles().stream().skip(1).findFirst().get());
WebElement printPreviewApp = driver.findElement(By.tagName("print-preview-app"));
WebElement printPreviewAppConten = expandShadowRoot(printPreviewApp, driver);
WebElement printPreviewSidebar = printPreviewAppConten.findElement(By.tagName("print-preview-sidebar"));
WebElement printPreviewSidebarContent = expandShadowRoot(printPreviewSidebar, driver);
WebElement printPreviewHeader = printPreviewSidebarContent.findElement(By.tagName("print-preview-header"));
WebElement printPreviewHeaderContent = expandShadowRoot(printPreviewHeader, driver);
printPreviewHeaderContent.findElements(By.tagName("paper-button")).get(1).click();
where expandShadowRoot function looks like:
private WebElement expandShadowRoot(WebElement parent, WebDriver driver) {
return (WebElement) ((JavascriptExecutor) driver).executeScript("return arguments[0].shadowRoot", parent);
}
Save button will not work because page is not part of webpage. selenium only support web based application.
But you can use SIKULI to handle above scenario.
I just tried to open the first search result of the youtube link.
Here is my code. Since the youtube results are in iFrame, I used SwitchTo.frame()method.
String browser = "Chrome";
WebDriver b = null;
if(browser.equals("Chrome")) {
System.setProperty("webdriver.chrome.driver", "C:\\chromedriver_win32\\chromedriver.exe");
b = new ChromeDriver();
}
else if (browser.equals("firefox")) {
b = new FirefoxDriver();
}
b.get("http://www.youtube.com/");
b.findElement(By.xpath("//*[#id='masthead-search-term']")).sendKeys("selenium tutorial for beginner");
b.findElement(By.xpath("//*[#id='masthead-search-term']")).sendKeys(Keys.RETURN);
b.switchTo().frame("pyv-iframe"); //youtube search results are in iframe
//b.findElement(By.linkText("Selenium IDE Demo - Quick Beginner's Tutorial")).click();
b.findElement(By.xpath("//*[#id='search-results']/li[1]/div[2]/h3/a/span")).click();
While running this code it returns as
Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element
at findElement By xpath. Please tell me what am I missing. Please see me as a newbie to Selenium.
I'm not sure why you are saying that the results are in an <iframe>... I'm not seeing an iframe. Here is your script using the getting started with selenium framework:
#Config(url="http://youtube.com")
public class YouTubeTest extends AutomationTest {
#Test
public void myTest() {
setText(By.id("masthead-search-term"), "selenium tutorial for beginner")
.click(By.id("search-btn"))
// navigate to a search result based on index
.click(By.cssSelector("ol#search-results > li:nth-child(X) a.yt-uix-tile-link"))
;
}
}
on the click(By.cssSelector you need to replace the X value with 1, 2, etc.. whatever the index of the link you want to click is.
(If you aren't using that framework you can easily translate the code and extract the selectors I use)
I did investigate on the Youtube page in Selenium IDE and it did get me these results:
driver = new FirefoxDriver();
baseUrl = "http://www.youtube.com/";
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.get(baseUrl + "/results?search_query=selenium&sm=3");
driver.findElement(By.id("masthead-search-term")).clear();
driver.findElement(By.id("masthead-search-term")).sendKeys("selenium");
driver.findElement(By.cssSelector("span.yt-ui-ellipsis-wrapper")).click();
Please note the last line: Thats where I clicked on the first search result. After investigating the Youtube page with Web Developer tools I realised that here is a iframe but it contains only some tracking code for AdSense (my guess)
General note: Always try to investigate with Selenium IDE first. It saved me from a lots of nightmares about my selenium code ;)
I am new to selenium. I am practicing to write a test case on http://www.countdown.tfl.gov.uk. Below are the steps I followed:
a) I opened the browser to selenium Web Driver
b) Found the search text Box and enter H32 and clicked on search button to selenium.
Till this part it works fine.
Now on the page I am actually getting two records on the left side of the page under the search. I am actually trying to click on the first one i.e. "Towards Southall,Townhall" link. Nothing is happening.
Below is my code:
public class CountdownTest {
#Test
public void tflpageOpen(){
WebDriver driver = openWebDriver();
searchforBus(driver,"H32");
selectrouteDirection(driver)
}
//open the countdowntfl page
private WebDriver openWebDriver(){
WebDriver driver = WebDriverFactory.getWebDriver("FireFox");
driver.get("http://www.countdown.tfl.gov.uk");
return driver;
}
private void searchforBus(WebDriver driver,String search){
WebElement searchBox = driver.findElement(By.xpath("//input[#id='initialSearchField']"));
searchBox.sendKeys(search);
WebElement searchButton = driver.findElement(By.xpath("//button[#id='ext-gen35']"));
searchButton.click();
}
private void selectrouteDirection(WebDriver driver){
WebElement towardssouthallLink= driver.findElement(By.xpath("//span[#id='ext-gen165']']"));
((WebElement) towardssouthallLink).click();
}
}
Please help me.
Thanks.
Since you are getting NoSuchElement Exception now, you may try the following code with the usage of WebDriver explicit wait.
WebDriverWait wait = new WebDriverWait(driver, 15);
WebElement towardssouthallLink = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("(//*[#id='route-search']//li/span)[1]")));
towardssouthallLink.click();
Or WebDriver implicit wait
WebDriver driver = WebDriverFactory.getWebDriver("FireFox");
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
driver.get("http://www.countdown.tfl.gov.uk");
Tips:
The search results need some time to be retrieved, so please use Explicit wait or Implicit wait.
Don't use locators like span[#id='ext-gen165'], they are ExtJs auto generated.
In this case, css selector can also be used: #route-search li:nth-of-type(1) > span
You aren't calling selectrouteDirection.
You probably want:
#Test
public void tflpageOpen(){
WebDriver driver = openWebDriver();
searchforBus(driver,"H32");
selectrouteDirection(driver);
}
You also don't need to cast here:
((WebElement) towardssouthallLink).click();
It's already a WebElement anyway.
I found that id for those links are dynamically generated. ids are of the form 'ext-genXXX' where XXX is number which is dynamically generated hence varies each time.
Actually, you should try with linkText:
For 'Towards Southall, Town Hall'
driver.findElement(By.linkText("Towards Southall, Town Hall")).click
For 'Towards Hounslow, Bus Station'
driver.findElement(By.linkText("Towards Hounslow, Bus Station")).click
Here is a logic:
Get all elements which have id starts with 'ext-gen' & iterate over it & click on link with matching text. Following is Ruby code(sorry, I don't know Java well):
links = driver.find_elements(:xpath, "//span[starts-with(#id, 'ext-gen')]")
links.each do |link|
if link.text == "Towards Southall, Town Hall"
link.click
break
end
end