In my selenium automation script, I am trying to click a "Policy" tab in the webpage by its xpath value.
Here is the actual html code:
....
<iframe src="/abc/api/public/v1/security/redirect">
#document
<!DOCTYPE html>
<html class="ng-scope" ng-app="CFWApp" lang="en">
<body>
<div class="container no-padding main-view flex-col">
::before
<cfw-menu class="ng-isolate-scope">
<div class="security-menu">
<ul class = "flex-row">
<li class="tab ng-scope active" ng-repeat="tab in $ctrl.items" ng-class="{'active': $ctrl.active == $index}" ui-sref="policy.templateList" href="#!/policy/template" style="">
<span class="tab-icon">...</span>
<span class='ng-binding'>Policy</span>
</li>
<li> ... </li>
</ul>
</div>
</cfw-menu>
...
</div>
</body>
</html>
And here is my Java code:
driver.findElement(By.xpath("//li[starts-with(#class = 'tab') and contains(#ui-sref = 'policy.templateList')]/span[2]")).click();
But somehow, this xpath setting not working. Can someone help me for that ? Thanks a lot !
For start you need to move to iframe
WebElement iframe = driver.findElement(By.xpath("..."));
driver.switchTo().frame(popframe);
After, you can use
driver.findElement(By.xpath("//span[text() = 'Policy']")).click();
But you need to be sure is not more spans which have text 'Policy' in that frame.
policy.templateList')]/span[2]")).click()
It will not work as you are trying to click a span element not the button.
Once I also trapped in such type of problem in python and then I use action class in selenium
First of all select any thing then by selenium action class pass tab key untill you get that element focused then pass enter key using action class that's it.
Good luck...
Related
Hi I'm wondering if there's a way to parse an entire HTML tag using JSoup? In my example pictures below, the five elements (4 images and 1 string) are all inside the "li" container. However, when you open the "li" tag, there are multiple nested containers. Is there a way to parse it so that I have access to all 5 elements contained in this "li" tag? I'm thinking of using getElementsMatchingOwnText("Collins") but that seems to only get me "span class="text text_14 mix-text_color7">Panorama". Any help would be appreciated, thanks!
Yes, you can iterate over the children of your <li> tag using jsoup.
Here is a simplified version of the HTML in your screenshot, showing the 5 elements:
<li>
<span class="foo"><img src="bar" class="img"></span>
<span class="bar">Collins</span>
<i class="baz1"><img src="baz1" class="img"></i>
<i class="baz2"><img src="baz2" class="img"></i>
<i class="baz3"><img src="baz3" class="img"></i>
</li>
Assuming you have selected this specific <li> tag in your document, you can use the following approach:
String html = "<li><span class=\"foo\"><img src=\"bar\" class=\"img\"></span><span class=\"bar\">Collins</span><i class=\"baz1\"><img src=\"baz1\" class=\"img\"></i><i class=\"baz2\"><img src=\"baz2\" class=\"img\"></i><i class=\"baz3\"><img src=\"baz3\" class=\"img\"></i></li>";
Document document = Jsoup.parse(html);
Element element = document.selectFirst("li");
element.children().forEach(child -> {
// do your processing here - this is just an example:
if (child.hasText()) {
System.out.println(child.text());
} else {
System.out.println(child.html());
}
});
The above code prints the following output:
<img src="bar" class="img">
Collins
<img src="baz1" class="img">
<img src="baz2" class="img">
<img src="baz3" class="img">
UPDATE
If the starting point is a URL, then you would need to start with this:
Document document = Jsoup.connect("https://www...").get();
Then the exercise is about identifying a unique way to find your specific element. So, if we update my earlier example, let's assume your web page is like this:
<html>
<head>...</head>
<body>
<div>
<ul class="vList_4">
<li>
<span class="foo"><img src="bar" class="img"></span>
<span class="bar">Collins</span>
<i class="baz1"><img src="baz1" class="img"></i>
<i class="baz2"><img src="baz2" class="img"></i>
<i class="baz3"><img src="baz3" class="img"></i>
</li>
</ul>
</div>
</body
</html>
Here we have a class in a <ul> tag called vList_4. If that is a unique class name, we can use it to jump to that section of the HTML page (IDs are better than class names because they are guaranteed to be unique - but I did not see any ID names in your screenshot).
Now, instead of my previous selector:
Element element = document.selectFirst("li");
We can use this more specific selector:
Element element = document.selectFirst("ul.vList_4 li");
The same results will be printed as before.
So, it's all about you looking at the page structure and figuring out how to jump to the relevant section of the page.
See here for technical details describing how selectors are constructed.
I am using selenium webdriver in java.I neead to click a menubar. i tried various xpaths and not working. <div class="menu-toggler sidebar-toggler"> </div> is the element i am trying to click. I used the xpath /html/body/div/div[4]/div[2]/div/div[2]/div[2]/div[2]/div/div/div[1]/div[2]/a.
I am fine with any option that would help me click the menu bar.Stuck here with automation.i use ngwebdriver framework so if it can be done using ngwebdriver is also fine.It would be really great if somebody could help me with this.
<div class="ng-scope" ng-if="loggedIn">
<div class="page-spinner-bar hide" ng-spinner-bar="">
<div class="ng-scope" data-ng-controller="HeaderController">
<div class="page-header md-shadow-z-1-i navbar navbar-fixed-top ng-scope" data-ng-include="'app/main/tpl/header.html'">
<div class="page-header navbar navbar-fixed-top ng-scope">
<div class="page-header-inner">
<div class="page-logo">
<div class="menu-toggler sidebar-toggler"> </div>
</div>
<a class="menu-toggler responsive-toggler" data-target=".navbar-collapse" data-toggle="collapse" href="javascript:;"> </a>
<img class="small-logo" src="assets/img/logo_kart_small.gif">
<div class="top-menu">
</div>
</div>
</div>
</div>
You should try using By.cssSelector() as below:
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement sideMenuButton = wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("div.menu-toggler.sidebar-toggler")));
Actions actions = new Actions(driver);
actions.moveToElement(sideMenuButton).click().perform();
Edited :- If unfortunately above does not work try using JavascriptExecutor to perform click as below :-
WebElement sideMenuButton = wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("div.menu-toggler.sidebar-toggler")));
((JavascriptExecutor)driver).executeScript("arguments[0].click()", sideMenuButton);
Try using firefox's firebug add on that has a built in xpath generator. It's a really accurate generator. Has solved many problems of mine even if I was using a different browser than firefox.
I've the below snippet, I need to find the Xpath to click on "Option1"
The Problem here is below two divisions are dynamically displayed based on the browser size or Screen Resolution
<div class="wrap">
<aside id="side-anchor-links">
<ul class="menu">
<li><a class="anchor-active">Option1</a></li>
<li"><a class="">Option2</a></li>
</ul>
</aside>
<main class="content">
<div id="wrapper">
<div id="scroller">
<div id="top-anchor-links" class="scroll-me">
<ul class="menu">
<li><a class="">Option1</a></li>
<li><a class="">Option2</a></li>
</ul>
</div>
</div>
</div>
</main>
</div>
Thanks is Advance.
My Trails:
xpath = //aside[#id="side-anchor-links"]/ul/li[text()="Option1"] //This option will work only when the options are displayed in the side view
xpath = //li[text()="Option1"] //This option will retrieve two occurances
Note: Always class="anchor-active" is associated with option1 in Side View until we click on any option from any division
Try with the below xpath :
//div[#class='wrap']/aside[#id="side-anchor-links"]/ul/li[1]
So, I believe you need to click at one element, and if it is not present - on another.
And if plain //li[text()='Option1'] does not suite you well, try this:
//*[#id='side-anchor-links' or #id='top-anchor-links']//li/a
Better customize your //li/a part, however
I am trying to automate the hover on a specified element, in my case is an specified office name.
When I hover on an office the information of it should appear.
My problem is that when I run his code:
String officeId = findElement(designOfficesPosition, num).getAttribute(ConstantsFramework.ID);
WebElement office = getSupport().getDriver().findElement(By.id(officeId));
action.moveToElement(office).build().perform();
getSupport().pause(ConstantsFramework.TIME_OUT_10_SECONDS);
I don't get any errors but I don't see the information of the office. Am I missing something? Any ideas? Thanks
UPDATE
Here you can see a piece of the html:
<div id="officesListPreview">
<div class="roundBox previewOffice officesRotator">
<h3>Office information</h3>
<p class="numbers">
<div id="OPA-AT" class="officeContainer" style="display: none;">
<div id="BPO-BG" class="officeContainer" style="display: block;">
<a class="officeLink" href="http://www.bpo.bg/" target="_blank" style="">
<div class="detailsOffice">
</div>
<div id="BOIP-BX" class="officeContainer" style="display: none;">
SOLVED
What I was missing is that there are two classes Actions and Action. I was using just Action class
This works perfectly!!
WebElement home = driver.findElement(By.xpath(//div[#id='homePage']));
Actions actions = new Actions(driver);
Action mouseOverHome = actions.moveToElement(home).build();
mouseOverHome.perform();
You can also try doing it via HasInputDevices interface.
RemoteWebElement homePage = (RemoteWebElement) driver.findElement(By.xpath(//div[#id='homePage']));
((HasInputDevices)driver).getMouse().mouseMove(homePage.getCoordinates());
I'm facing the following problem.I can not type text in iframe in which there is a text editor:Here is the html:
<iframe class="cke_wysiwyg_frame cke_reset" frameborder="0" style="width: 100%; height: 100%;" aria-describedby="cke_39" title="Текстов редактор за форматиран текст,description1" src="" tabindex="0" allowtransparency="true">
<!DOCTYPE html>
<html lang="bg" dir="ltr">
<head>
<body class="cke_editable cke_editable_themed cke_contents_ltr" contenteditable="true" spellcheck="false">
<p>
<br>
</p>
</body>
</html>
</iframe>
Here is what I have done so far,but the test passed successfully and no text is writen in the text editor.May be the solution is with Javascript executor but I'm not familiar with it.
WaitTool.waitForElementPresent(Browser.instance, By.tagName("iframe"), 10);
WebElement iframe = Browser.instance.findElement(By.tagName("iframe"));
Browser.instance.switchTo().frame(iframe);
WebElement description=Browser.instance.findElement(By.xpath("//body[#class='cke_editable cke_editable_themed cke_contents_ltr']"));
description.click();
description.sendKeys("someText");
Browser.instance.switchTo().defaultContent();
Thanks in Advance!
There are multiple ways of doing it. Here's an article you might want to have a look.
Test WYSIWYG editors using Selenium WebDriver
Send keys directly
This approach is the one you have tried and didn't work. Please try make sure your locators to <iframe> and <body> are correct. Otherwise I'd suggest using JavaScriptExecutor for more stable solutions.
Set innerHTML
WaitTool.waitForElementPresent(Browser.instance, By.className("cke_wysiwyg_frame"), 10);
WebElement iframe = Browser.instance.findElement(By.className("cke_wysiwyg_frame"));
Browser.instance.switchTo().frame(iframe);
WebElement description = Browser.instance.findElement(By.cssSelector("body"));
(JavascriptExecutor)Browser.instance.executeScript("arguments[0].innerHTML = '<h1>Set text using innerHTML</h1>'", description);
Use CKEditor's native API
// no need to switch iframe
(JavascriptExecutor)Browser.instance.executeScript("CKEDITOR.instances.ckeditor.setData('<h1>Native API text</h1> Editor')");