Expect an element by xpath to have specific text - xpath

After pressing a save button a box will pop up and say if it was success or failed. The box has the same xpath no matter the result.
expect(element(by.xpath('path example')));
Inside the HTML for the element it says
<div class="panc lm-he" style="....."><span style="..."> Saved!</span></div>
edit -- oops it's early.
I want to know how can I have the expect come back true if the text "Saved!" is there or not. So if "Saved!" is present inside that element then it's true otherwise it's false.

Try with showing the output of the entire element like this:
element(by.xpath('path example')).then(function(element){
console.log(element);
});

not sure I understand want you want, but this way you will check if div with 'Saved!' text is Displayed
expect(element(by.xpath('.//div[text(), "Saved!"]')).isDisplayed).toBe(true);

As #Gunderson notes it doesn't matter what locator you use, the syntax will be the same. When I want to confirm text in an element I usually do something like this:
myElement.getText().then(function (text) {
expect(text).toContain(message)
});
That way you can tell by looking at the failure if the element didn't show up at all, or if it is visible but the text is not displayed, or if everything is fine and the test passes. So in your case it would just be
element(by.xpath('path example')).getText().then(function (text) {
expect(text).toContain('Saved!')
});

Related

Inconsistent element query with Cypress

I'm trying to use Cypress to click a react-select element. However, I get very inconsistent results.
My code for clicking the element is as follows:
cy.get('div[class*=container]').contains('Brand').click()
Sometimes this works, sometimes it doesn't. Sometimes if I repeat this line twice (which is kind of hacky...), it works, but on other occasions it doesn't...
What would be the correct and fool-proof way to wait for this element to properly load and click it only then in Cypress?
I looked into this cypress repo and it suggested two way to do the click().
cy.contains('.product', 'First item')
.find('button.order')
.click()
.wait(1000)
cy.contains('.product', 'First item')
.find('button.order')
.click()
.click()
Because its a select element, what you would want to do is:
cy.get('div[class*=container]').select('Brand')
or
cy.get('div[class*=container]').contains('Brand').realClick()
Looking at examples of react-select, there are a lot of classes with container in them, so 'div[class*=container]' is not the best selector.
I understand class*=container is to circumvent the style hash which can change on compile.
Ideally, add a specific class to the source, as per the first example on the home page
<Select
className="basic-single"
...
then you have a link to the top-most element, which is clickable.
cy.visit('https://react-select.com/home')
cy.get('div.basic-single')
.should('contain', 'Ocean')
.click()
cy.contains('Green').click() // option selection
cy.get('div.select__control').eq(0)
.should('contain', 'Green')

How to get the text of hidden check boxes inside a scroll bar using Selenium WebDriver?

I'm trying to automate Filter By Brand scenario in BigBasket and now stuck up in a situation where my code could not print the brand names that are hidden inside a scroll bar.
Steps to follow
Go to www.bigbasket.com
Click Skip & Explore button
Search Apple and view the list of brands on the left side
#FindAll({#FindBy(xpath="//*#id='filter_brands_list']/div/div1/li/label")})
List chkBrands;
The above lines of code identifies all the brand names but when I print them using the below code I can see only the brand names that are visible
for(WebElement eachElement:chkBrands){
System.out.println("No. of brands is "+chkBrands.size());
System.out.println(eachElement.getText());
}
Could you please let me know the solution? I apologize that I could not think of a solution as I'm an amateur in Selenium.
WebElement.getText() will return the text of the element only if it is displayed on the screen.
Meaning if the isDisplayed method returns false then getText()method will return empty.
Explanation with Examples Here
As defined in WebDriver spec, Selenium WebDriver will only interact
with visible elements, therefore the text of an invisible element will
always be returned as an empty string.
However, in some cases, one may find it useful to get the hidden text,
which can be retrieved from element's textContent, innerText or
innerHTML attribute, by calling element.attribute('attributeName') or
injecting JavaScript like return arguments[0].attributeName.
So you can get the text by textContent attribute
eachElement.getAttribute("textContent")
Try this one:
JavascriptExecutor je = (JavascriptExecutor)driver;
WebElement element = driver.findElement(By.xpath("Your_xpath"));
String text_value = ((JavascriptExecutor) driver).executeScript("return arguments[0].innerHTML;",element);

How to set a span value with capybara?

Does anyone know how to set a value to span tag using capybara?
I tried using element.set or element.send_keys, they only selected the targeted element without modifing the previous value.
<div data-offset-key="bbpvo-0-0" class="_1mf _1mj"><span data-offset-key="bbpvo-0-0"><span data-text="true">aa</span></span></div>
HTML snippet is above, I want to set aa to bb.
Capybara is designed to emulate a user - A user can't edit a span unless there's some sort of javascript widget attached to it. If you have a JS widget attached to the span you would need to perform whatever actions a user would do in order to edit the span. So you say the user has to click on the span and then type on the span - if that is so then you could try something like
span = find('span[data-text="true"]')
span.click
span.send_keys("new content", :enter) # if enter is needed to end the editing
which may work - although I'm going to guess the element actually gets replaced with an input or something after it's clicked on, in which case you need to figure out what those elements are (using the browsers inspector) and then find and use send_keys or set on that element instead
To set text in span value,jquery can be used with capybara as shown below:
page.execute_script("$("<span css selector>").text("testing")");
or
page.execute_script("$("<span css selector>").html("testing <b>1 2 3</b>")");

How do I identify a dynamic-id custom-type text field in WATiR?

I have this input of type "Submit" that Watir cannot see. I can identify it by ID, but it doesn't turn up in browser.text_fields, or by any other idenfication method. The ID is dynamically generated so I cannot use it for testing. Any ideas on how to make this readable? I'm willing to change the WATiR source code if necessary.
<INPUT id=t8CPm value=Submit type=submit>
I have obviously tried text_field(:value, 'Submit') and text_field(:type, 'Submit'), and I get an "Unable to locate element" error.
Did you try treating it as a button element? Inputs of type submit are generally considered to be a button because the browser generally renders them that way.
try
browser.button(:value, 'Submit').flash
and see if it works for you
I changed INPUT_TYPES to ["text", "password", "textarea", "submit"] in the TextField class of input_elements.rb and there it was.
I should also probably edit the collections to read the type too.
Edit: I am an idiot and I didn't need to do this, but I'm leaving it here in case anyone else needs to identify a real dynamic-id custom-type text field, not a fake dynamic-id custom-type text field otherwise known in my particular case as a "button".

How do you get Length of Text in a Mojo TextField?

How do you get the length of the text inside a Mojo TextField?
I'm trying to set a multiLine TextField with a limit of 150 chars, I tried doing it with a counter, but ran into a issue of not being able to decrement the counter when the text was erased, or adding the right number when pasting text, so my new approach was to get the length of the text each time you press a letter.
I've already tried this: (gets called in the charsAllow attribute of the textField)
if (this.controller.get("mensaje").mojo.getValue().length <= 150) {
return true;
}
this.controller.get("mensaje").mojo.blur();
return false;
but it doesn't work.... I debugged and the function exits just after the line in bold... it doesn't even returns true or false.
I also tried assigning the length value to a variable or assigning the text to a variable and then get the length, but nothing.
It's the same issue. It returns just after the getValue().
Also, maybe because of this issue, the text scrolls instead of wrapping, but when the textField loses focus it wraps the text.
If 'mensaje' is the HTML id of your text field, try getting it and using .innerHTML().length. In other words, work with the DOM element using Javascript/Prototype functions instead of the Mojo object.
My first guess would be that "this" isn't being passed into charsAllow properly. Did you .bind(this) the function you're passing as an argument?
I found this a little odd... the function mojo.getValue() actually works... but not from inside the function called by "charsAllow"..., and also, the function called by charsAllow can't call any other function, it just breaks out of the function doing nothing... does someone have a way to limit the chars in a MultiLine TextField??? (mojo textfield, to preserve the look :D). Thanks!!
this blog explains a bit about text fields might be useful:
http://kmdarshan.com/wordpress/?p=3305

Resources