Protractor assertion passes with the xpath locator but not with the classname locator.
Works
var menu = element(by.xpath('/html/body/page/div[1]/div[3]/div[2]/div[1]/span'));
Passes it's assertion.
Fails
var menu = element(by.classname('menu'));
Yields the following errors:
In chrome,
Failed: element not interactable
In firefox,
Failed: Element could not be scrolled into view
Why might this be?
by.classname() will be convert to by.css() by protractor inside.
by.classname('menu') will be convert to by.css('.menu').
Try css selector: .menu manually in chrome DevTools and check the first element found by .menu is same as by the xpath: /html/body/page/div[1]/div[3]/div[2]/div[1]/span.
We're not able to suggest any reliable css selector without seeing DOM, especially when you don't use menu class in your xpath selector.
If you want to convert it into css selector, you can try:
element(by.css('page > div:nth-of-type(1) > div:nth-of-type(3) > div:nth-of-type(2) > div:nth-of-type(1) >span')); or any shorter equivalent.
Here was the problem, I had multiple elements with the same classname. What protractor was doing was taking the first element with that class. What it should have been doing was taking the second but related element with that class.
I tried element.all(by.className('menu')).get(1) and it works perfectly.
Thanks for your help #yong and #Kacper for pointing me in the right direction.
Related
i am trying to Automate flipkart website in which i am trying to change address but "add new adress" is not getting clicked i have attached the snapshot
my code is like driver.findElement(By.xpath("//*[#id='ng-app']/div/div[2]/ul/li[2]/div/div[2]/div[2]/div[2]/a/span")).click();
please give the appropriate help
I doesn't look that you are clicking active element, the xpath is //*[#id='ng-app']/div/div[2]/ul/li[2]/div/div[2]/div[2]/div[2]/a/span not correct it clicks on some span.
Use Firepath https://addons.mozilla.org/en-US/firefox/addon/firepath/ to get the xpath.
To ensure that button is clickable Use isDisplayed() and isEnabled() method before clicking on "Add New Address" button, this method return boolean value.
driver.findElement(By.xpath("//*[#id='ng-app']/div/div[2]/ul/li[2]/div/div[2]/div[2]/div[2]/a/span")).isDisplayed();
driver.findElement(By.xpath("//*[#id='ng-app']/div/div[2]/ul/li[2]/div/div[2]/div[2]/div[2]/a/span")).isEnabled();
Also you can verify that element is exist on page or not using below code
if(driver.findElements(byVal).size()!=0){
// Element is present.
}
hope it may helpful to identify cause of issue, why its not clickable.
First and foremost, Use a customized Xpath instead of the one you are using which is extracted directly from the browser. If no customized Xpath can be constructed then try a customized Css or any other locator if possible.
Try to go through the following attempts in order (I hope you can grasp why this is):
1- If .click() still doesn’t work, then keep on changing the values of the attributes you are using to construct your customized xpath, cssSelector, or locator.
2- Use the Actions class.
3- Use JavaScript executioner
4- instead of click(), try using any of: .sendKeys(“\n”). Or .sendKeys(keys.ENTER) or .sendKeys(keys.RETURN)
I tried to locate an element on the page with the following but couldn't do.
element(by.css('.organizer-text.ng-binding')).click();
element(by.className('organizer-text')).click();
element(by.linkText('All Cases(1)')).click();
element(by.css('span[class="organizer-text"]')).click();
element(by.css('span[ng-class="{'folder-selected' : isSelected(node)}"]')).click();
element(by.css('span[title="All Cases (1)"')).click();
element(by.xpath('div//span[title()="All Cases(1)"]')).click();
Attaching the screenshot of the element with the DOM. Could you please help me on how to locate it?
<span class="organizer-text ng-binding"
tooltip="buildLabel(node.name, node.totalCases)"
ng-click="onLabelClick($event, node)"
ng-class="{'folder-selected' : isSelected(node)}"
ng-show="!node.showEditName" title="All Cases (1)">
All Cases (1)
</span>
The structure is div->span->multiple spans here (one of the spans here is the element)
try
element(by.xpath('//span[#title="All Cases(1)"]')).click();
I used browser.ignoreSynchronization = true; after logging into the page and it worked.
Looks like you found your answer yourself. But, this is for your own information. Just try this work flow out.
Right-click of your element and get the inspect element window.
Go to inspect element of the element and right-click
There will be a window with some options
Select copy Unique Selector option.
element(by.css('paste your Unique Selector here')).click();
Like step 5 paste your unique selector
Hope this helps. :)
I have used Selenium WebDriver and CSS Selector for a while. Today i came across this below css selector (see image)
the highlighted element's cssselector is:
#sf-menu > li:nth-child(1) > ul:nth-child(2)
as provided by browser inspect element functionality, and it is confirmed by firefinder.
I am quite surprised. I am not an expert on CSS Selector, but the answer it's given means "find the 1st li under sf-menu, then the 2nd ul under the previous".
But from the image, clearly it is 'the 1st ul under the previous', and the HtML tab shows there isn't even a 2nd ul exist.
What's going on here? Thanks.
That first and only ul is the second child of the li (after the a).
I have a pagination list, that is essentially constructed like so (I am using AngularJS):
<span id="latestResultsIndicator">
<ul>
<li ng-click="Item.action()"><span>1</span></li>
<li ng-click="Item.action()"><span>2</span></li>
</ul>
</span>
This works great in HTML, but when I try to write an integration test using Selenium WebDriver and the Fluent API I run into problems.
Specifically I want to click on the second li, to do this I am using the following code
I.Assert.Exists("#latestResultsIndicator");
var secondPageElement = I.Find("#latestResultsIndicator ul li:nth-child(2)");
I.Click(secondPageElement);
This doesn't actually work! If I use jQuery in the Chrome console to do $("#latestResultsIndicator ul li:nth-child(2)").trigger("click") then the second page is selected, so I know the selector is correct.
To test further I added a double click like so:
I.DoubleClick(secondPageElement);
What I noticed here is that the very first li gets selected. Its as if its trying to click or select the wrong one! (See the image).
What is happening?
I know Webdriver has some issues with css pseudo-selectors such as nth-child. You might be able to make it work with Xpath, which is just as fast and just as flexible.
var webDriver = (IWebDriver)I.Provider;
webDriver.FindElement(By.XPath("//*[#id='latestResultsIndicator']//ul//li[2]")).Click();
Not sure if it will work or not, as I have not used FluentAutomation.
The CSS selector as it is written in your question is not correct
"#latestResultsIndicator ul li:nth-child(2)"
The UL has the id you're looking for, so it should be
"ul#latestResultsIndicator li:nth-child(2)"
Not sure whether that is going to solve your problem, but it's a place to start. If not, please update with the results
Is it possible to get an element by its name like you can with jQuery?
I'm trying to do the equivalent of the jQuery selector like in jQuery
$('h1')
how is this done with protractor?
I tried
element('h1')
but it doesn't work
There's a couple ways to do this - you can either get it by tagName or by css selector. So any of the following work:
element(by.css('h1')); // works with any css selector
$('h1'); // works with any css selector
element(by.tagName('h1'));
The answer was finally found on github they have a test file that shows all the selectors
element(by.css('h1'));
element(by.css('.my-class'));