Is there any method to identify the following in Selenium?
Number of iframes in a page
Attributes/Details of the current iframe
driver.findElements(By.xpath("//iframe")).size();
For acquiring details of current frame I propose you switch to it using a WebElement object and switchTo, and then get attributes like you normally do, with getAttribute
UPD
In fact, yes, first will give the amount of iframes in current context. If you don't want to do it recursively, but want a quick and working (dirty) solution - just get the page source and find all inclusions of "<iframe" string
As the other answers have stated, you can identify the number of frames in the currently focused context using:
driver.findElements(By.xpath("//iframe")).size();
However this will not identify any frames that are children of another frame. To do so, you will need to switch to that parent frame first.
To retrieve attributes such as name or id for the currently focused frame you can use JavascriptExecutor like so:
String currentFrameName = (String)((JavascriptExecutor) driver).executeScript("return window.frameElement.name");
Here an example how you can approach it:
WebDriver driver = new FirefoxDriver();
driver.get("http://the-internet.herokuapp.com/iframe");
// find all your iframes
List<WebElement> iframes = driver.findElements(By.xpath("//iframe"));
// print your number of frames
System.out.println(iframes.size());
// you can reach each frame on your site
for (WebElement iframe : iframes) {
// switch to every frame
driver.switchTo().frame(iframe);
// now within the frame you can navigate like you are used to
System.out.println(driver.findElement(By.id("tinymce")).getText());
}
Related
I am doing automation using selenium webdriver (java) on a search engine BookMyCrop (http://www.bookmycrop.com). Here, I searched for a crop but, I am not able to click on desired search result. Please help me with it.
Code :
WebElement search = driver.findElement(By.xpath("//*[#id=\"search_keyword\"]"));
search.sendKeys("59825");
search.sendKeys(Keys.ENTER);
driver.findElement(By.partialLinkText("Cashew")).click();
------My 1st try-------------
//WebElement link = driver.findElement(By.xpath("\"//div[#id = 'Links']/a[3]\""));
//link.click();
------My 2nd try-------------
//List<WebElement> find = driver.findElements(By.xpath("/html/body/section[2]/div[2]/div/div/div/div[1]"));
//find.get(1).click();
}
} –
You can use the css selector based on class names: ".product-block.inner-product-block" and get the list of all the search results.
Then click on whatever index you want to click.
I am not using an IDE for this but it would look something like this:
driver.findElements(By.cssSelector(".product-block.inner-product-block")).get(0).click();
As said, you can try with css ".product-block.inner-product-block"
Then
get List of WebElements
do loop
inside loop, try get text of each element or innerText attribute
cross check if it is required one or not by simple if condition
If so, click on that web element and break loop
if this locator is not giving required info, try other locator. say $$("a h3") for veg names.
The below code worked for me. It is navigates to the correct link
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().setScriptTimeout(20, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.get("http://www.bookmycrop.com");
WebElement search = driver.findElement(By.xpath("//*[#id=\"search_keyword\"]"));
search.sendKeys("59825");
search.sendKeys(Keys.ENTER);
driver.findElement(By.partialLinkText("Cashew")).click();
I'm trying to use selenium to type in data in inputboxes. But I cant get any element (NoSuchElementException). Problem is only with this site.
I tried searching by name/id but it failed.
WebDriver driver = new FirefoxDriver();
driver.get("https://ekrs.ms.gov.pl/web/wyszukiwarka-krs/strona-glowna");
System.out.println(driver.getCurrentUrl());
System.out.println("Successfully opened the website");
WebElement wb = driver.findElement(By.id("rejestrPrzedsiebiorcy"));
My goal (for now) is just to get this element :P.
The problem is the form is included in the source via <iframe> element. You can see that it has attribute src="https://ekrs.ms.gov.pl/krsrdf/krs/wyszukiwaniepodmiotu?". If you go to that link, you will see standalone form. The question is - how to access an included source? It's quite simple ;)
Find the <iframe> element:
WebElement frame = driver.findElement(By.xpath("//div[#class='portlet-body']/div/iframe"))
Switch to that frame:
driver.switchTo().frame(frame)
And that's it! Now you are in the <iframe> element context, and you can search inside it. so this will work now:
WebElement wb = driver.findElement(By.id("rejestrPrzedsiebiorcy"));
To switch back (get out of the frame context) you just have to call:
driver.switchTo().defaultContent();
Note that this site has dynamically generated ids to prevent automation, and uses CaptchaV3 (you can see I used xpath expression to find the iframe). Selenium is easily detectable if you are not careful.
Carefully observe the HTML code after inspecting required element. If you element is inside <iframe> then you need to switch on to frame first and then find that element.
below is the way to switch to frame:
driver.switchTo().frame() method takes one of the three possible arguments:
A number.
Select a frame by its (zero-based) index. That is, if a page has three frames, the first frame would be at index 0, the second at index 1 and the third at index 2. Once the frame has been selected, all subsequent calls on the WebDriver interface are made to that frame.
driver.switchTo().frame(0)
A name or ID.
Select a frame by its name or ID. Frames located by matching name attributes are always given precedence over those matched by ID.
driver.switchTo().frame("name here");
A previously found WebElement.
Select a frame using its previously located WebElement.
WebElement iframeElement = driver.findElement(By.id("IF1"));
//now use the switch command
driver.switchTo().frame(iframeElement);
Try driver.findElement(By.id("form-main")); first, then driver.findElement(By.id("rejestrPrzedsiebiorcy")); again.
I am trying to automate some tests on my node webkit app using Java Selenium. The way it works is that the chromedriver attaches to the main window, but any site that I access is in the DOM as a webview like so:
Picture with the DOM:
How would I approach this? After expanding the shadow root element in java and trying to switch the context to the iframe below it, I just get random errors (in my opinion) that do not pertain to the function I'm calling. For example:
WebElement shadowRoot = expandShadowElement(root);
WebElement iframe = shadowRoot.findElement(By.cssSelector("iframe"));
Driver.getWebDriver().switchTo().frame(iframe);
WebElement city = Driver.getWebDriver().findElement(By.className("input-btn-group"));
The second line gives me a "Argument to isShown must be of type Element", but that does not make sense as I am not calling the isShown function.
As per your question, once you expanding the shadow root element induce WebDriverWait for the desired <iframe> to be frameToBeAvailableAndSwitchToIt as follows:
WebElement shadow_root = Driver.getWebDriver().findElement(By.xpath("//webview[#class='sel' and contains(#src,'https://www.google.com/?')][starts-with(#id,'w_Webo')]"));
WebElement shadow_root_element = (WebElement)((JavascriptExecutor)driver).executeScript("return arguments[0].shadowRoot", shadow_root);
new WebDriverWait(Driver.getWebDriver(), 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.tagName("iframe")));
Note: As per the screenshot you have shared the element identified as By.className("input-btn-group") isn't visible and is not included within the answer.
We can switch to iframe inside shadow dow by following these 3 steps
step 1: get the shadow root element
step 2: Using that shadow root element find the iframe web element
step 3: Now switch into the iframe which we got in step 2
loc = Locator.new(:xpath,"//locator_used_to_get_shadow_root")
sr = #driver.gets_shadow_root(loc)
iframe_inside_shadowroot = sr.find_elements(:css, "iframe")
driver.switch_to.frame(iframe_inside_shadowroot)
Solve similar issue for electron. In electron they have their own wrapper on top of webview, that based on Chromium webview.
But for chrome webdriver solution's may be the same.
https://stackoverflow.com/a/63227482/4577788
Please check out the element of this website.
It has a form, and along with 2 text input and 1 submit button.
I dont know which one from those 2 inputs that is actually used when the user type-in some urls over there.
But when I tried this (using firefoxDriver) to get the element:
WebElement textfieldURL = driver.findElement(By.id("ping-url")); // even ping-box not working
The result's unable to locate the element.
Then I change my code to this :
driver.switchTo().frame(driver.findElement(By.className("ping-iframe")));
WebElement textfieldURL = driver.findElement(By.id("ping-url")); // even ping-box not working
The result's still unable to locate the element.
Any clues?
You haven't mentioned the exception which you are facing. As your input tag present under iframe so you need to first switch into frame and than have to perform actions -
driver.switchTo().frame(driver.findElement(By.className("ping-iframe")));
//or you can use frame index as well
driver.switchTo().frame(0);
your element is available with the id ping-box . Try the following complete code -
System.setProperty("webdriver.gecko.driver","D:/Application/geckodriver.exe");
driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.get("https://www.twingly.com/ping");
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.switchTo().frame(driver.findElement(By.className("ping-iframe")));
driver.findElement(By.id("ping-box")).sendKeys("http://www.google.com");
driver.findElement(By.id("ping-button")).click();
Same is working for me.
I have searched all the forums but I didn't get a correct answer for my issue. My web page to test has a link hidden below, and I am trying to find it manually by searching for it with xpath or the ID attribute of the element, but I am not able to find it when I am running the web driver script. Even when it is not giving any error on that element, I am getting an error on next command/line.
I found below code from the forums, which is scrolling whole page. I don't want this, I want to scroll down vertically in a specific div area as in screen shot.
JavascriptExecutor jsx = (JavascriptExecutor)driver;
jsx.executeScript("ctl00_Menu1_scrollDiv.scrollBy(0,250)", "");
div id for this is "ctl00_Menu1_scrollDiv"
Element id: ctl00_Menu1_DlMenu_ctl09_LnkMenuname
Please help me on this issue. Thanks in advance.
Help will be appreciated.
This is umendra tomar , I have found very simple solution for this, please use the below code for scroll a specific div in html using selenium .
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("document.getElementById('scrollCustom').scrollTop= 450");
scrollCustom = this is the ID of your div which you want to scroll.
document.getElementById = this is use in javascript to locate a webelement.
Don't worry we can use this in java using javascriptExecutor
Check if this works for you.
var s = $('#ctl00_Menu1_scrollDiv').scrollTop();
This will give the current value of the scroll in the div.Use this only if you want to scroll inside a div to a certain point dynamically. Otherwise you can hardcode the scrollTop value inside animate()
Using the current value of your scroll you can parameterize the given below scrollTop parameter
$("#ctl00_Menu1_scrollDiv").animate({ scrollTop: "100px" }); // Here 100 px is just an example
I had used this to scroll a large div programmatically in my webdriver framework. Also, this will work if your AUT has jQuery loaded in the browser.
In Java:
JavascriptExecutor js;
js = (JavascriptExecutor) driver;
js.executeScript("$(\"#ctl00_Menu1_scrollDiv\").animate({ scrollTop: \"100px\" })");
First you should not just reference an element by the id. You should set scrollTop to scroll it to a position.
document.getElementById("ctl00_Menu1_scrollDiv").scrollTop(250);
Non-JQuery solution based on this post.
((JavascriptExecutor) driver).executeScript(
"arguments[0].scrollTop=arguments[1].offsetTop",
divWithScrollbarElement,
elementToScrollTo);
where divWithScrollbarElement is the div element which you are looking to scroll, and elementToScrollTo is the child element which you want to make viewable (which in my case was actually the parent of the element which I was initially trying to view). If elementToScrollTo is not actually in the DOM yet, you may need to use the script once to scroll down as far as possible, and then again once more elements have loaded.