I'm a tester, and I have this HTML code.
<div id="columns">
<div class="column ce-editable c1">
</div>
</div>
I'm using Cypress. I want to examine if there is 'c1' class name found in the div element. If I try:
cy.xpath ('//div[#id="columns"]//div')
.should('have.class', 'c1')
I have this error:
CypressError: Timed out retrying: You attempted to make a chai-jQuery assertion on an object that is neither a DOM object or a jQuery object.
The chai-jQuery assertion you used was:
> class
The invalid subject you asserted on was:
> [<div.column.ce-editable.c1>]
To use chai-jQuery assertions your subject must be valid.
This can sometimes happen if a previous assertion changed the subject.
May I give you a whole other direction. It goes far, far away from using Xpaths :). What you can do to archive what you want is the following:
cy.get('#columns')
.find('div')
.should('have.class','c1')
This results in a few positive things:
1. It's easier to read what is happening
2. Debugging is easier, you'll see that Cypress tries to verify c1 in three steps. First find some ID with 'columns', than find a div below that and finish with asserting that the last searched div has a class called 'c1'.
3. The results show more neath since should() is actual an assertion instead of an action.
Related
I need to extract a number from an HTML page and convert it into a variable in my test case.
The problem is that there is no ID directly to this element, here is the HTML code, I want to get the 54 (that number can change that's why I need to identificate him with another way), I tried Get Text by using "resultat" but I get "54 ligne(s) trouvée(s)" but I only want "54":
<div class="tab-interpage> == $0
<div class="resultat">
<b>54</b>
ligne(s) trouvée(s)
</div>
...
You have other options how to locate an element, see Locating elements section in Selenium Library.
This might be a situation that requires xPath, I can imagine this one works (but I don't see the whole DOM, so I can't be 100 % sure):
//div[#class="resultat"]/b
combined with the keyword:
${var}= Get Text //div[#class="resultat"]/b
Obviously if there're more div elements with class "resultat", you might run into problems here. In this case, explore the DOM a bit more and see what are some other ways you can get to the element you need.
I think it'd be much more readable if the HTML elements had proper attributes like:
form with class attribute
unique ids usually work best
Let's consider the case where I need to assert if an element exists. There are 2 possible ways of doing this in cypress:
1) cy.get('button').contains('Save')
2) cy.get('button').contains('Save').should('exist')
In both cases the test will fail if the 'Save' button not exist.
What are the reasons apart from maybe better code readability/maintainability that I should add the .should('exist') to my cypress tests?
For your usecase of asserting whether an element exists, they are indeed redundant.
.contains() yields a DOM element and according to documentation, .should yields the same element it was given as an input. There are some exceptions when .should yields different element (as you can see in the documentation) but in case of using should('exist'), they are really redundant
As you mentioned, I personally also prefer adding should for better readability. Actually I prefer .should('be.visible') because of following scenario - when an element is hidden or is pushed out of the screen because of some CSS issues, it doesn't exist from user perspective. But..
cy.get('button').contains('Save') - passes test
cy.get('button').contains('Save').should('exist') - passes test
cy.get('button').contains('Save').should('be.visible') - fails test
Actually, until v4.0 is released (and this PR is merged), you need to chain should('exist') assertion if you chain any negative assertions yourself. This is because the default should('exist') assertion is skipped when you chain your own assertions.
Not necessary for positive assertions because they won't pass on non-existent elements.
Also see Implicit should 'exist' assertion is not being applied on cy.get() when other assertion.
Below, the element .first-item does not exist but the assertion passes:
describe('test', () => {
it('test', () => {
cy.get('.first-item').should('not.have.class', 'is-selected');
});
});
From my test,
cy.get('button').contains('Save').should('exist')
is not redundant.
It's true that, if it contains Save, your test is successful. If it doesn't, your test fails with the desired reason description. In that aspect, should('exist') is redundant.
However, if you do cy.get('button').contains('Save'), and the button exists, you only get a grey step which means the step is executed without error. But it does not show a green assert badge, because you don't have an assertion there.
So I could suggest removing line 1) and keep line 2).
Then if it passes, you get a green assert badge. If it fails, it actually fails at contains('Save') part rather than should part. But anyway, you get red error with meaningful error messages.
Although, I do agree with #Durkomatko that 'be.visible' is better if you do want it to show on the page.
hi how to use Get Element Attribute in Robot framework? in instruction I have
Return value of element attribute.
attribute_locator consists of element locator followed by an # sign and attribute name, for example element_id#class.
I have this xpath=${check_radio_xpath}#class is this right way?
where ${check_radio_xpath} = md-radio-11
I get this error:
${ischecked} = Selenium2Library . Get Element Attribute xpath=${check_radio_xpath}#class
Documentation:
Return value of element attribute.
TRACE Arguments: [ 'xpath=md-radio-11#class' ]
DEBUG Finished Request
FAIL ValueError: Element 'xpath=md-radio-11' not found.
I think you're pretty close. Please try to format your question better, I took a quick shot because your question is difficult to read. The result will be more and better help from the community
${RADIO_XPATH} //*[#id="${check_radio_xpath}"]
${CLASS}= Selenium2Library.Get Element Attribute ${check_radio_xpath}#class
sample for this <div><label for="foo"></label></div>
${for_value}= Get Element Attribute xpath=//div/label for
Log To Console ${for_value}
console result is:
foo
This snippet works for me :
Get Line Numbers And Verify
${line_number1}= Get Element Attribute //*[#id="file-keywords-txt-L1"] data-line-number
Log To Console ${line_number1}
${line_number2}= Get Element Attribute //*[#id="file-keywords-txt-L2"] data-line-number
Log To Console ${line_number2}
Verify in order of ${line_number1} and ${line_number2} is true
What was important is that the spaces/tabs between the keywords are correct, otherwise it does not get recognised as a so called keyword.
Thanks a lot, i wanted to check meta noindex content in page source.
i used this.
${content} Get Element Attribute xpath=//meta[#name="robots"]#content
should be equal as strings ${content} noindex,follow
You can use both XPath and CSS selector if you have selenium library
${title}= Get Element Attribute ${xpath} attribute=title
I am using Selenium to automate app creation test. The test includes filling out fields on a web page and clicking a submit button. Once that is done, a new page loads with an alert stating success or failure. The problem for me is, the alert is coded in a css class as follows:
<div class="alert-box notice">
Successfully created application
×
</div>
All I need to do is verify the text "Successfully created application" exists. I do not need to manipulate anything.
I'm not sure what language you are doing, but basically, you need to get the text in the containing div.
So, for example,
driver.findElement(By.cssSelector(".alert-box.notice")).getText()
After some discussion with my peers and much online research, here is the solution I found.
At first I tried capturing the text based on Nathan's suggestion, but decided to store the results as a string.
String happy = driver.findElement(By.className("alert-box notice")).getText();
assertEquals(true, happy.contains("Successfully"));
The problem with this is that I kept getting errors such as, "org.openqa.selenium.InvalidSelectorException: The given selector alert-box notice is either invalid or does not result in a WebElement. The following error occurred:
InvalidSelectorError: Compound class names not permitted"
Since I have no control over the class name, I went the xpath route as follows:
String happy = driver.findElement(By.xpath("html/body/div/div[2]/div/div/div/div[3]/div")).getText();
assertEquals(true, happy.contains("Successfully"));
This version runs correctly and I am able to verify the alert message.
I have the following code, where I need to get the value:
<a href="/checkout/cart.jsf">
Items:
<span class="numberofitems">1</span>
</a>
However, when I attempt to point at it using css=span [class='numberofitems'], I get the message "The element has no value; is it really a form field?" The element does have a value which I can see in Firebug, but I can't figure out how to properly store this value.
Here we go.. every WebElements given below will give better outcome to get the value '1'.
By.xpath("//a[#href='/checkout/cart.jsf']/span")
By.xpath("//a[text()='Items: ']/span"))
By.xpath("//span[#class='numberofitems']")
If they are not working,
Check whether the Elements are HIDDEN with help of Firebug.
Check whether the classname, 'numberofitems' is repeated.