Select node by value - puppeteer - javascript

I have a simple script in which I am trying to test the functionality of some buttons. Inside of my html I have a button:
<button> MyList </button>
In my script I tried the following:
...
await page.type('button[value="MyList"]');
await page.click('button[value="MyList"]');
This was a shot in the dark as I could not find a way to select an element by value in the puppeteer docs. Obviously it cannot find it and I get the error: 'No node found for selector: button[value="AccountList"]'

This is because the button's value is not MyList. MyList is the text content of the elment which is different than the value which is an attribute. In CSS you cannot query for elements by their text contents. Since there is no such native CSS selector that will work for your use-case, you have to traverse the DOM manually and look for the matching nodes.
There is such selector implemented in jQuery -
:contains(). I guess you can use some similar library for Node.js.

Related

Cypress How do tick check boxes with no unique selectors

I am trying to select/tick checkboxes with no obvious selectors but a class name which is shared by all the checkboxes on the page.
Then You can directly use the text to find the locator and click it, something like:
cy.contains('Tool').click()
For the search button, you have the aria-label tag, you can use that directly:
cy.get('input[aria-label*="main-search-box"]').type('text')
I believe it goes against cypress' best practices to try and select any element other than using data-cy="add-unique-id-here" selector. The docs suggest that using CSS-style selectors is brittle, and may cause tests to fail in the future when you update your code. By using data-* selectors, you can gaurantee you're always selecting what you need.
Here's the link for the cypress docs: https://docs.cypress.io/guides/references/best-practices#Selecting-Elements
In your case, adding
<span class="ui-lib-checkbox__box" data-cy="descriptive-checkbox-name"> <svg>...</svg> </span> to your html
and cy.get('[data-cy=descriptive-checkbox-name]') to your cypress testing file, should do the trick.
Given the text for the checkboxes are unique, you can use cy.contains()
// 'Under 6 min' checkbox
cy.contains('span', 'Under 6 min')
// 'Tool' checkbox
cy.contains('span', 'Tool')
As for the search box, it will get a bit trickier. If it is the only search box that is visible on the page you can do the following.
cy.get('input[type=text][placeholder]')
.filter(':visible')

How to set a span in JS instead of making a alert

Kind of a newbie to this but I have followed a totorial on a memory game as an attempt to understand the syntax of JS but am stuck on making the round result print in a instead of showing up as a alert
here is a codepen here.
how can I print round in a <span> <!-- result here--> </span> rather than like this alert("result")
How can I make it set to a span instead of being an alert?
Browsers parse HTML into a tree of objects called Document Object Model (DOM). Using JavaScript you can query the DOM to get individual nodes, and then change them.
To get your span, you would typically use document.getElementById or document.querySelector (there are other functions that can fetch collections of related nodes, like document.getElementsByClassName or document.querySelectorAll). The former identify nodes by the property named in the method name (ID, or class name, respectively); the latter ones use CSS selectors. (All of the getElement... functions can be replicated using the newer querySelector and querySelectorAll interface, though you have to know how to use CSS selectors. I almost never use getElement... functions any more.) There are also functions that use XPath, though this is a bit more advanced subject.
Once you have the node, you can change its content using e.g. .textContent or .innerHTML properties, the former being for plain text, the latter for HTML.
For example, if this is the only span on the page, this suffices:
document.querySelector('span').textContent = "Result";
<span></span>
If on the other hand you have more of them, you would need some way to target the correct one. I will also demonstrate how you can style it using HTML:
const node = document.querySelector('#result_goes_here');
node.innerHTML = "<strong>Result</strong> in bold!";
<span id="result_goes_here"></span>
If you are trying to add the result inside the HTML SPAN and not in the alert box. You can do it something like this:
document.getElementById("span_ID").innerHTML = the_variable_result_here;
Hope that helps!

Nightwatch. Click on element with text

I have a problem, can`t click on web element having some unique text.
I have this structure:
<div class="wg-wagon-type__item" data-reactid="10"
<div class="wg-wagon-type__title" data-reactid="11">Text</div>
I try this
.click('.wg-wagon-type__title:contains("Text")')
But I have an error
ERROR: Unable to locate element: ".wg-wagon-type__item .wg-wagon-type__title:contain("Text")" using: css selector
How can I correct click on this element?
Is there any reason why you can't simply target the class wg-wagon-type__title?
.click('.wg-wagon-type__title')
Unfortunately there isn't a CSS selector that matches on the text of an element. However, nightwatch has the capability to run javascript on the browser via 'api.execute' and that allows you to do string matching.
Alternatively, you could use an xpath selector and use that to match the text
.click("//div[contains(#class, 'wg-wagon-type__title') and text()='Text']")

Selecting the proper HTML Element

I use Nightwatch.js to test foreign website code. I used this command:
.waitForElementVisible('input[id="inputField"]', TIMEOUT)
This should wait until the specified element is visible. But I get this warning:
Warn: WaitForElement found 24 elements for selector "input[id="inputField"]". Only the first one will be checked.
I thought the id of a tag is unique. How is it possible to get a list of 24 elements when looking for this id?
What can I do now to select exactly the element I need?
How is it possible to get a list of 24 elements when looking for this id?
Because people constantly fail to understand the basic concept that ids must be unique. Apparently, the site you're testing against was written by one or more of those people.
What can I do now to select exactly the element I need?
According to the documentation, Nightwatch.js lets you use XPath as an alternative to CSS. With XPath, you can specify which of a set of elements to target, e.g.:
.useXpath()
.waitForElementVisible('//input[#id="inputField"][1]', TIMEOUT)
...would use the first, [2] would use the second, etc.
If you can't do it by the index of the element in the document, you'll need to find other things about it you can use to select it (with CSS or XPath).
The id of an element should be unique. However that doesn't take out the ability for a developer to create as many elements with the same id on the page as he wants.
Also, id selectors are usually specified like this input#inputField.
I could now solve the problem by selecting an unambiguous parent element and then selected the child of the child of it; something like this:
div[id="listItem_0"] > span > input[id="inputField"]

Can I select an element by its array position in nightwatch.js?

I am looking to automate some of my testing processes and I am relatively new to Nightwatch.js and javascript. Is there a way that I can click an element based on it's class and position in the subsequent array that will be returned if there are multiple elements with the same class.
For example take the following HTML: -
<div class="clickable-button"><p>Some Text</p></div>
<div class="clickable-button"><p>Some Text 2</p></div>
<div class="clickable-button"><p>Some Text 3</P></div>
If I use chrome development tools and run the following command in the console: -
$('.clickable-button')
It returns an array of the three elements listed above.
I would like to click the first <div> element and want to know if there is a way I can do this using a CSS selector? I cannot select via the text that appears within the <p> tag as this is dynamic data.
I have tried the following commands in Nightwatch: -
browser.click('.clickable-button'[0])
browser.click('clickable-button[0]')
Neither of these options work. Any help or advice would be appreciated.
You could probably use :nth-of-type
browser.click('.clickable-button:nth-of-type(1)');
BTW :nth-of-type is part of CSS3 so it is not supported by older browsers.
Besides using CSS selector, XPath is another option, you can do
browser
.useXpath() //ignore this line if you already selected xpath as strategy
.click('(//div[#class="clickable-button"])[1]')
to locate the first button. Reference

Categories