Enzyme simulate with 1 node - javascript

I have the following test case in react-native.
it('changes text', () => {
wrapper.find(InputBox).simulate('change', { target: { value: 'text Given' } });
});
There are 2 InputBoxes so this gives me an error saying 'simulate should run on a single node, but found 2'.
How can I fix this issue?

You could make use of selectors such as first or at. For instance, say you want to select the first InputBox, you will write:
wrapper.find(InputBox).first().simulate('change', { target: { value: 'text Given' } });
In the same way you can use last to get the last of matched nodes or at(index) to select matches by index.

Related

it statement inside loop iteration for each expect statement, mocha

I have this array of objects.
let links = [
{
url: 'some url 1',
status: 200
},
{
url: 'some url 2',
status: 200
}
]
Which is the result of calling LinkFunction asyncronously inside before:
before(async () => {
try {
links = await LinkFunction();
} catch (err) {
assert.fail(err);
}
});
I would like to check if the url and status properties exist and if their types are correspondingly string and number.
Note: The specified object is just a sample of a big response. So the loop is required for iteration in any case.
I've done this iteration:
it('Array to contain some props', () => {
links.map(property => {
expect(property).to.have.property('url').to.be.a('string');
expect(property).to.have.property('status').to.be.a('number');
});
});
But I would like to have something like this:
it('Array to contain some props', () => {//or describe would be better here
links.map(property => {
it('link array to contain url string', () => {
expect(property).to.have.property('url').to.be.a('string');
});
it('link array to contain status number', () => {
expect(property).to.have.property('status').to.be.a('number');
});
});
});
Unfortunately it statements are ignored inside map. Maybe it's because of the several nested it statements. So How can I implement a similar logic?
Update:
My full code:
You might want to use forEach instead of map.
Also, "Passing arrow functions (aka "lambdas") to Mocha is discouraged" so you will probably want to change those to normal functions.
Having said that, it works fine if links is defined as mocha initially runs the test file and collects the individual it tests:
const expect = require('chai').expect;
describe('links', function() {
let links = [
{
url: 'some url 1',
status: 200
},
{
url: 'some url 2',
status: 200
}
]
links.forEach(function(property) {
it('link array to contain url string', function() {
expect(property).to.have.property('url').to.be.a('string');
});
it('link array to contain status number', function() {
expect(property).to.have.property('status').to.be.a('number');
});
});
});
..results in:
> mocha
links
√ link array to contain url string
√ link array to contain status number
√ link array to contain url string
√ link array to contain status number
4 passing (14ms)
Update
As you have found, it only works at the top level or with a describe:
before(function() {
it('will NOT work here', function() { });
});
it('will work here', function() {
it('will NOT work here', function() { });
});
Also, links must be available while the test is first running and the it tests are being collected by mocha so this doesn't work either:
describe('links', function() {
let links = [];
before(function() {
links = [
{
url: 'some url 1',
status: 200
},
{
url: 'some url 2',
status: 200
}
];
});
// This won't work...
links.forEach(function(property) {
// .. since links is still an empty array when this runs
it('should...', function() { /* ... */ });
});
});
From your question update it looks like your code retrieves links from an async function call in before. Because of this, there is no way to have links populated at the time the test is first running and the it tests are collected.
So it looks like you won't be able to map across the items in links to create your it tests, and will instead need to take the approach you described by mapping across the items in links within a single test.

Trying to understand browser.elementIdText command

I couldn't find much information or useful examples to understand how this method works on a Javascript UI testing framework. I have the following element which is returned in an array:
console.log(elementarray[0]);
{ ELEMENT: '25',
'element-6066-11e4-a52e-4f735466cecf': '25',
selector: '[data="abc"]',
value: { ELEMENT: '25' },
index: 0 }
however when I run:
browser.elementIdText(elementarray[0].ELEMENT)
I see this:
{ state: 'success',
sessionId: 'af7ef2fb-7d1d-456e-ad14-c5c1fd9d83c2',
hCode: 1013623656,
value: '17:55',
class: 'org.openqa.selenium.remote.Response',
_status: 0 }
How exactly is browser.elementIdText working here, can anyone provide a simple explanation with an example pls. I see information here that I am not seeing when I log the first item in the array and surely the value of elementarray[0].ELEMENT is just 25 right? as it's shown in the first property of the object?
Thanks for any useful replies.
elementIdText expect ID as argument. In order to get ID, you need to use allElem.value[0].ELEMENT for example. See below code.
describe('allx', () => {
it('allx', () => {
browser.url("https://the-internet.herokuapp.com/");
allElem=browser.elements('//div[2]/div/ul/li/a');
console.log(allElem.value[0].ELEMENT)
text=browser.elementIdText(allElem.value[0].ELEMENT).value;
console.log(text);
});
});

How do I select the root node in jstree?

I am trying to embed some functionality in my jstree based on whether it is a root node or if it is one of the child nodes.
From the jstree documentation and other Stack Overflow posts that I have gone through, I am now able to populate the items correctly, but I am at a roadblock on how to select the root node of the jstree in an "select_node" condition like the following snippet. Is this correct appending the word "root" to select_node? Please advise. (My root item is called "root", if I have to call get_parent() and check how would I pass my root as paramter). Any pointers to proceed would be appreciated.
$(".myjstree").on("select_node.jstree.root", function (e, data){
// do stuff if this is my root node
});
Listening to select_node.jstree.root does not work as intended, as all it does is create an additional namespace for select_node.jstree (see the Event names and namespaces section from http://api.jquery.com/on/ for more information). select_node.jstree.root events are still triggered for all select_node.jstree events.
Instead, you can check whether the root node is selected via the data.selected property in select_node.jstree. You can also interact with it via $('#jstree').jstree(true).get_node('root') like so:
$('#jstree').jstree({
core: {
data: [
{
id: 'root',
text: 'Root',
state: { opened: true },
children: [
{ id: 'child-node-1', text: 'Child 1' },
{ id: 'child-node-2', text: 'Child 2' }
]
}
]
}
});
$('#jstree').on("changed.jstree", function (e, data) {
if (data.selected.length === 1 && data.selected[0] === 'root') {
let root_node = $('#jstree').jstree(true).get_node('root');
console.log(root_node);
}
});
#import "https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css";
<div id="jstree"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script>

How to iterate through querySelectorAll results in Nightwatch

I can't seem to find the correct syntax for iterating through the innerHTML of a nodelist in Nightwatch. I'm trying to return the urls of every 'a' tag contained within the body content of a page, but I can't find a way to access the results of my querySelectorAll command in Nightwatch.
browser.execute(function() {
return document.querySelectorAll("div.field-item.even a");
},
function(tags){
console.log(tags.value);
console.log(tags.value[9]);
})
There are 10 links on the page I am testing. The query selector seems to be retrieving them all, since console.log(tags.value) prints the following:
[ { ELEMENT: '1' },
{ ELEMENT: '2' },
{ ELEMENT: '3' },
{ ELEMENT: '4' },
{ ELEMENT: '5' },
{ ELEMENT: '6' },
{ ELEMENT: '7' },
{ ELEMENT: '8' },
{ ELEMENT: '9' },
{ ELEMENT: '10' } ]
and console.log(tags.value[9]) prints:
{ ELEMENT: '10' }
I cannot find a way to retrieve the link from these results, however. Appending .innerHTML to any of these variables returns 'undefined'. Is there any way for me to iterate through the querySelectorAll results and retrieve the urls inside of it?
EDIT: It seems like I can get the same result if I use the following code:
browser.elements("css selector", "div.field-item.even a", function(tags) {
console.log(tags.value);
console.log(tags.value[9]);
})
I originally thought that I was working with a nodelist, but I think I'm actually being returned a WebElement JSON object as per the documentation for the .elements command.
I'm still unable to access the inner text, however. Any ideas?
I resolved the issue using a different method. I used the browser.elements command instead of querySelectorAll, and then used browser.elementIdAttribute to get the contents of each 'href' attribute in each 'a' tag.
//Get an WebElement JSON object array of all urls
browser.elements("css selector", "div.field-item.even a", function(link_array) {
for (var x = 0; x < link_array.value.length; x++){
//Fetch the url from each 'a' tag in the content
browser.elementIdAttribute(link_array.value[x].ELEMENT, "href", function(links) {
console.log(links.value);
});
}
})
This prints out every link within the content of the page.
selectAllRoles: function (client) {
client.elements('css selector', '.editorDetail ul li input[type=checkbox]', function(res) {
res.value.forEach(elementObject => {
client.elementIdClick(elementObject.ELEMENT);
});
});
return this;
},
Fill in your id's after the 'css selector'

Looping through links via WebDriver

I am currently testing a web page via WebDriver I/O. I would like to be able to select a couple of links and "click" them. Currently, I have the following:
it('Should click links', function(done) {
client
.elements('a').then(function(links) {
console.log(links);
console.log('---------');
for (var i=0; i<links.value.length; i++) {
client.getAttribute(links.value[i].ELEMENT)
}
expect(true).toBe(true);
done();
})
;
});
When I execute this test, I see the following in the console window:
{ state: 'success',
sessionId: '85d25e09-13d8-475a-81b6-87431d2d8f3c',
hCode: 1234567890,
value:
[ { ELEMENT: '0' },
{ ELEMENT: '1' },
{ ELEMENT: '2' } ],
class: 'org.openqa.selenium.remote.Response',
status: 0 }
---------
{ ELEMENT: '0' }
{ ELEMENT: '1' }
{ ELEMENT: '2' }
My question is, how do I "click" the link? When I printed out the link, I was expecting to see an ID, an href, an xpath, or some way to reference the link. But I don't see anything. When I look at the docs, they mention that the elements are returned as WebElement JSON objects. However, I can't seem to find any docs on WebElement.
What am I missing?
You tell it to click on the element, just like the docs say: http://webdriver.io/api/action/click.html
In your case, the code would be something like:
it('Should click links', function(done) {
client
.elements('a').then(function(links) {
console.log(links);
console.log('---------');
for (var i=0; i<links.value.length; i++) {
client.click(links[i])
}
expect(true).toBe(true);
done();
})
;
});
Your code will probably be different, but this should get you started. Now, a couple of quick points:
1) You should avoid having mulitple assertions inside a test. It violates OAPT and can make your tests harder to find when one is failing.
2) You might check out Protractor (http://www.protractortest.org) for E2E testing. It doesn't require Angular and it can make your testing life a lot easier.

Categories

Resources