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.
Related
I am using this code, but it's not working but xpath in the picture is correct. I am not allowed to use (//h2//a[#class='question-link'])[2] because I need to use previous webelement:
driver.get("https://stackexchange.com/");
WebElement e = driver.findElement(By.xpath("//h2//a[#class='question-link']"));
WebElement f=e.findElement(By.xpath(".[2]"));
System.out.println(f.getText());
The second element you want is just another element that is located by the first locator. The easiest way to do what you are asking is to change the first statement to use .findElements() (plural) and then get the second element returned.
List<WebElement> e = driver.findElements(By.xpath("//h2//a[#class='question-link']"));
System.out.println(e.get(1).getText()); // index starts at 0 so 1 is the second element
Instead of again writing Webelement f write the complete xpath including [2] in Webelement e itself.
Here is an example in Python using Selenium to extract the text from the second link using a previous WebElement:
from selenium import webdriver
initialize the browser
driver = webdriver.Firefox()
navigate to the website
driver.get("https://www.example.com")
locate the previous WebElement
previous_element = driver.find_element_by_css_selector("#element_id")
locate the second link relative to the previous WebElement
second_link = previous_element.find_elements_by_tag_name("a")[1]
extract the text from the second link
text = second_link.text
close the browser
driver.quit()
Note: Replace #element_id with the actual id of the previous WebElement and make sure to install the Selenium library if not already installed.
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.
Link: http://www.bbc.com/weather/
Scenario: Type "reading" on the find a forecast text box. This shows 2 options. How do I select one option using Selenium WebDriver?
I am using the following command to type "reading"
driver.findElement(By.id("locator-form-search")).sendKeys("Reading");
I added explict wait as you suggested and this worked with a small change in the css path. This is what I did:
WebElement suggestedList = new WebDriverWait(driver, 15)
.until(ExpectedConditions.elementToBeClickable(By
.cssSelector("div[class='locator-suggestions locator-suggestions-default'] >ul >li:nth-of-type(1)")));
driver.findElement(
By.cssSelector("div[class='locator-suggestions locator-suggestions-default'] >ul >li:nth-of-type(1)"))
.click();
Use the following locator to click on the first element (first suggestion displayed after typing):
driver.findElement(By.cssSelector("div[class='locator-suggestions locator-suggestions-default'] li:nth-child(1)")).click();
Similarly you can click on the other element by changing the locator. For example to select the second element:
driver.findElement(By.cssSelector("div[class='locator-suggestions locator-suggestions-default'] li:nth-child(2)")).click();
Just to add here, you may need to wait for the elements/suggestions (which you're trying to select) to be visible, before trying to click on those. Use/search for a appropriate wait method for your testing.
So,
first you need to type "reading" in the field as you are doing by using driver.findElement(By.cssSelector("input#locator-form-search")).sendKeys("Reading");
then wait for element to be visible
Then try the above mentioned code to select the desired element.
Hope this helps.
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());
}