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']")
Related
I'm doing automation test and I need to input text in a text field, but the problem is there is no 'input' to do this.
This one won't work:
document.querySelector([class*=modal-dialog] [class*=AddCitation_] [class*='DraftEditorPlaceholder']).value='Hello World'
Does any one know how to input text in draft.js?
You can use document.execCommand("insertHTML", "html string here", false)
As you can see draft js uses contenteditable property of div to write text
So if you want to automate tests with draftjs insert any sample html string with command
so you have a sample text in draft editor now you can perform tests
Read this
https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand
Let's first understand the code you have written:
document.querySelector([class*=modal-dialog] [class*=AddCitation_] [class*='DraftEditorPlaceholder']).value='Hello World'
This code attempts to:
get the first element
which has a class containing 'DraftEditorPlaceholder' and
which has an ancestor having a class containing AddCitation_ which
has an ancestor having a class containing modal-dialog
So, you will first need to ensure that the element you try to edit is inside an element having a class containing modal-dialog. In your screenshot we cannot see such an ancestor element, the root having a class of modal-content. If the selector you have written does not find an element, then an error will be thrown when you try to assign a value to any of its attributes, like value in this case. You have an element having a class of styles_AddCitation__3_D5j, which is the child of the element of the class of modal-content. You have an element having a class of public-DraftEditorPlaceholder-root, which, assuming that you have a class containing the modal-dialog text being its ancestor, then the selector will find it. However, this is the sibling of the element which you seem to expect to find with your query. So, you will need to sort out where you intend to put your text into.
Now, assuming that you have sorted your selector out and there is a span in the element you are talking about, you will need to write span at the end of your selector, with a space before it. Also, in this case you will need to set innerText instead of value to your desired value. If the target element is an input, then setting a value should suffice.
Another possible problem is that your Javascript code might run before the structure is actually generated, hence not being able to set attributes of elements which do not exist yet. So you will also need to make sure that your structure is in place indeed when this Javascript code runs.
const screen = document.getElementById("screen");//get span ID
screen.innerHTML += `<span class="screen" >${
this.textContent
}</span>`);//add text content
<body>
<h1>CALCULATOR</h1>
<!-- <div class="container"> -->
<div class="container">
<div class="column2" id="screen">
<!-- <span class="screen"></span> -->
</div>
I used this to insert span tags into a div tag.
I'm only a beginner so it might not be optimal
I used this while experimenting with JS on a simple calculator, because I wanted to see if it could work without using an input tag.
please let me know if this helps as it will also help me to see if my understanding is good
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.
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
For debugging purposes, this is what I tried to type in Chrome Console:
$("#loading")
> null
But if I do this, it correctly retrieves the div:
$("loading")
> <div id="loading" align="center" style="display: none;">
I'm using jquery-1.4.1.min.js.
<script type="text/javascript" src="../../js/jquery-1.4.1.min.js"></script>
This doesn't make sense to me, why can I not select a div by # sign but I can when I exclude it?
Edit: Sorry, huge fail on my part. I meant the other way around. Please see the revised question.
The only other js library i have is prototype.js, which is loaded after jquery script.
$("#loading") indicates to get dom with specific id for that # sign is used.
without # jQuery will not recognize dom with id.
Similarly to get specific DOM with class name you has to use .
Some example selectors are :
Selector Example Selects
* $("*") All elements
#id $("#lastname") The element with id="lastname"
.class $(".intro") All elements with class="intro"
.class,.class $(".intro,.demo") All elements with the class "intro" or "demo"
I have checked at my side and see the result.
You should have a look at the jQuery selector documentation.
Some basic rules when using jQuery selectors follow (these are by no means exhaustive, you should look at the docs):
Using a # at the beginning of your selector will search for all DOM nodes with an id of whatever word follows the #. So $('#loading') will select DOM nodes with id="loading". This should only return one element, since non-unique ids on a page are invalid HTML.
Using a . at the beginning of your selector will do a similar search to #, but will look at all DOM nodes' class attributes instead and select those with a class matching your selector. So ('.loading') will select DOM nodes with loading in their class attribute's value.
Using simply a word with no preceding symbols will attempt to select all DOM nodes whose element tag name matches your selector's word. So $('loading') will attempt to find all <loading> tags, but since this isn't an actual HTML tag, nothing will be selected.
EDIT
So while the above is true, it seems that you had conflicts between prototype.js and jQuery. These are well known and much lamented. You can look at jQuery's wiki entry on using jQuery with other libraries and the documentation on jQuery.noConflict() for more information on this. Essentially, you will need to use jQuery instead of $ to access the jQuery library.
$("loading") indicates that you are selecting an html element tag like <div> tag ($('div')).
$("#loading") indicates that you are selecting an html element tag with id like <div id='loading'>.
Have a look at jquery selectors... http://api.jquery.com/category/selectors/
Currently I'm trying to select a link element with the jQuery :contains selector. This works when the contents of the link is just text. but it seems that when the element contains other HTML elements the :contains selector selects a child element instead. Example
HTML:
<b> two</b> this not bold <b>This</b> is a bold Link
from that html, I'm trying to select the link using this selector
jQuery:
var selector = "a:contains('<b> two</b> this not bold <b>This</b> is a bold Link')";
var returnObj = $(selector);
Instead of getting one returned object (the link), jQuery returns three objects:
the first bold element
the text this is not bold
the second bold element
the problem isn't the single quotes within the contains(), as I've tried with and without them.
This is just a simplified example of what I'm trying to do. In reality, I'm dynamically creating selectors based off of a link object a user clicks. I then store that selector in a database for use later (for my app to display content related to that link). Since I can get the contents of the link, I figured I'd just use a:contents() if the link doesn't have an id.
based off of these pages, I seem to have my syntax right:
http://docs.jquery.com/Tutorials:How_to_Get_Anything_You_Want_2
http://api.jquery.com/contains-selector/
Thoughts on how to get the link object returned? Thanks!
hope this isn't too stupid a question, I'm new to JS and jQuery.
As mentioned, :contains() is meant to select by text content only, not inner HTML.
If you must match the a element based on that text, strip out the <b> tags:
var selector = "a:contains(' two this not bold This is a bold Link')";
Otherwise, see if you can simplify this selection by using a contextual selector (e.g. select based on its surrounding elements, parents, siblings, etc), or assign it a class and select by that class instead.
On a side note, I'd consider this yet another jQuery bug (could be a parsing error in Sizzle). In your situation, :contains() is not supposed to return or create any elements; it's supposed to return no matches simply because the selector doesn't match your a element. I suspect what it's doing instead is treating the <b></b> tags as new elements, and creating them on the fly along with your a element, which is wrong because the tags are inside the argument string and meant to be taken literally...
First of all your selector text does not match the actual text in your html.
The selector includes the this not bold which is not present in the html.
Most importantly the :contains works with the text only.. so you should check for
$("a:contains('two this not bold This is a bold Link')");
It is a very inefficient way though, and you should better add a class to the elements you want to target and use that for targeting..