I mean when we initialize Selector like this:
let stringLocator = 'some element locator'
selector = new Selector(stringLocator)
is that possible to get original string locator somehow like this:
selector.locator
p.s. This question is related to this one where I've found some hacky workarounds to get testcafe display my xpath locators in error.
Testcafe does not support this, but you can use the following approach
function createSelector (locator) {
return Object.assign(Selector(locator), { locator });
}
const selector = createSelector('#button');
console.log(selector.locator)
I had the same issue yesterday. The apiFnChain contains the fnChain you used for the selector. It is behind a symbol. This is what helped me. Maybe this will help you too.
const selector = Selector('button.explore-button').withText('Explore the site')
const selectorFnChain = selector[Object.getOwnPropertySymbols(selector)[0]].options.apiFnChain
console.log(selectorFnChain)
This will give you this:
Selector('button.explore-button'),.withText('Explore the site')
You don't have to get the entire chain but this was the most helpful for me.
Related
In selenium query for selector, if my selector value was (#div-id a). It return all a tags.
Does in testcafe is it posible this to selector function? i just want to avoid looping to get all a tags.
Code Sample
const element = selector('#div-id').find()
var get = await brandUrls.hasAttribute();
console.log(get);
Actual element attached
Yes, it is also possible to achieve the desired behavior with TestCafè in a similar way:
import { Selector } from "testcafe";
// one option
const firstLinkSelector = Selector("#directoryLink-1 a");
// another option
const secondLinkSelector = Selector("#directoryLink-1").find("a");
Read more about the find()-method here.
So while testing my application, I am using a data set. Since the data set has many entries, I am using FlatList to display my list. After creating the list, I want to be able to verify and tap on certain list items. Below, I have attached the code which I am trying to use and it does not work for me. If anyone has a better idea to do this, please let me know.
The approach I think should be taken. I can't think of anything else to make the FlatList scroll and find the item I am looking for.
let isNotFound = true;
while (isNotFound) {
try {
await waitFor(element(by.id((edit_details.index).toString()))).toBeVisible().withTimeout(2000)
isNotFound = false;
} catch (e) {
await element(by.id('credit_history_list')).swipe('up', 'slow', 0.2)
}
}
await element(by.id((edit_details.index).toString())).tap();
It does help scroll the list and it keeps scrolling while it actually finds the entry I am looking for. But the .tap() function does not work. Instead, detox moves on with the next line of code.
Is there a better way to do this?
Thanks in advance!
This sounds spot-on with Detox' whileElement() API.
I think that what you're looking for is this:
const itemId = (edit_details.index).toString();
const listId = 'credit_history_list';
await waitFor(element(by.id(itemId))).toBeVisible()
.whileElement(by.id(listId))
.scroll(100, 'down');
I have this piece of code:
getText: (selector) => {
browser.waitUntil(function () {
return browser.isExisting(selector) === true;
},timeout,
'Could not find element after: ' + timeout,
pollingTime);
return browser.getText(selector);
}
And sometimes this function (getText(selector), but in deep browser.getText(selector)) returns undefined for the selector that looks like this:
article[data-product-id="test-00020"] li.product-entry__summary__item.is-price span
This doesn't happen every time test is run, but it happens occasionally. It is driving me nuts because the behavior is inconsistent. Sometimes it works and sometimes it doesn't.
Did anybody have similar problems? Please help! Thank you.
getText is dependent on the element being visible in the viewport of the page (so if it's scrolled off the page it will return an empty string)
Instead, you can use getHTML(false) to get the text content of an element (just ensure it's the inner-most element, otherwise you'll get HTML elements in the returned content)
If you use getHTML which I also did, you can strip out the HTML tags if they are not innerHTML:
var strArray = browser.getHTML("//div[myxpath]");
for(var i =0; i<strArray.length; i++){
strArray[i]=strArray[i].replace(/(<([^>]+)>)/ig, "");
strArray[i] = strArray[i].trim();
}
sorry for the Hungarian notation.
I'm having a heck of a time trying to write a test where I check that text on a button matches a certain string. I tried ".valueContains", ".attributeContains" and got blank or null, and I've tried getText(), but that only seems to return an object.
I feel like it's something obvious I'm missing, so any help would be appreciated!
Based on what you have written so far in your question, I am wondering if there is there a reason you cannot use .containsText?
.waitForElementVisible('.yourclass', this.timeout)
.assert.containsText('.yourclass', 'Text of Button you expect to match')
http://nightwatchjs.org/api#assert-containsText
Without actually looking at the code its little difficult to predict whats going on. However all of the methods in selenium return a promise, so you need to wait for it to resolve.
function async getTextOfButton() {
const element = await driver.findElement(By.className('item-class'));
const text = await element.getText();
}
If you are not using async/await you could do
driver.findElement(By.className('item-class')).then(function(element) {
element.getText().then(function(text) {
console.log(text);
});
});
I have tried every single thing to perform dragAndDrop using webdriverio but nothing works. I have also posted a question in the webdriverio gitter but no response. below posted code is one of the ways I tried and its supposed to work but it just doesn't!
` await this.driver.moveToObject(source);
await sleep(2000);
await this.driver.buttonDown(0);
await sleep(2000);
await this.driver.moveToObject(destination);
await sleep(2000);
await this.driver.buttonUp(0);`
I'm not sure what properties are on the source and destination objects you are using but here is an example of how I was able to get it to work using the same commands you are trying.
In my example I have a table with columns that can be re-ordered by dragging and dropping them wherever I want them to be. First I get the two column headers I want to switch
let docIdHeader = browser.element('div[colid="documentid1"]');
let pageCountHeader = browser.element('div[colid="_PAGE_COUNT1"]');
If I log these objects out to the console I can see the properties stored in them.
> docIdHeader
{ sessionId: 'e35ae3e81f1bcf95bbc09f120bfb36ae',
value:
{ ELEMENT: '0.3568346822568915-1',
'element-6066-11e4-a52e-4f735466cecf': '0.3568346822568915-1' },
selector: 'div[colid="documentid1"]',
_status: 0 }
> pageCountHeader
{ sessionId: 'e35ae3e81f1bcf95bbc09f120bfb36ae',
value:
{ ELEMENT: '0.3568346822568915-2',
'element-6066-11e4-a52e-4f735466cecf': '0.3568346822568915-2' },
selector: 'div[colid="_PAGE_COUNT1"]',
_status: 0 }
Now using the same technique you are using and the selector property off of these objects I can get it to work in two ways.
browser.dragAndDrop(docIdHeader.selector, pageCountHeader.selector);
Or
browser.moveToObject(docIdHeader.selector)
browser.buttonDown(0)
browser.moveToObject(pageCountHeader.selector)
browser.buttonUp(0)
I ran this in the REPL interface so I know it works as I could see each step being executed after I sent the commands. If you are not familiar with how to use the REPL I highly recommend learning. You can play around with commands in the console until you figure something out and then add those commands to your tests.
Also, as I stated in my comments above. dragAndDrop() and moveToObject() are going to be deprecated soon and you will likely see a lot of warnings about it when you use these. The correct way to implement a drag and drop action going forward is to use browser.actions(). Unfortunately, I don't have an example of how to do it that way as I haven't played with it yet. If no one provides an example by tonight I will try to get one together for you.
Even I faced this issue wherein the cursor doesn't move to the destination object after buttonDown and using moveToObject twice worked for me.
await this.driver.moveToObject(source);
await this.driver.buttonDown(0);
await this.driver.moveToObject(destination);
await this.driver.moveToObject(destination);
await this.driver.buttonUp(0);