How to count previous siblings in TestCafe? - testing

Summary:
I'm using TestCafe and I know it's not a difficult question which I'm asking (JQuery has a solution for this). I'm looking for a solution in TestCafe.
Question:
I need to know how many (count in integer) previous siblings (button) exists from the highlighted blue. In my case the answer should be 4.
What I've done so far
As per the screenshot, I'm in the element index 4 (but I don't know). I've used following selector to reach the element:
Selector('div.group-name').withExactText('f61ck72g83m')
Now, to count the previous sibling I tried this:
Selector('div.group-name').withExactText('f61ck72g83m').parent('button.group-info').prevSibling('button').count
and this returns a promise which I don't want:
ReExecutablePromise { _then: [], _fn: [Function], _taskPromise: null }

I missed await before calling the element. Silly question indeed.

Related

Storing and reusing the text content of an object using Playwright and Javascript, then use it for assertion/validaton

I would like to store the text from an object locator and use it for assertion. For instance, I have a trade number - 1234. This trade number only appears after a transaction, so it is not static on other screens. This number is located on several other screens and I need to validate that it appears. I am able to locate the element through inspect and Playwright accepts it, but having issues:
Grabbing the text (1234)
Then setting up an assertion statement to compare it
Below are my humble and naïve attempts:
async getConfirmNumber() {
//Store the contents in the page locator which has the trade number
const tradeNumber = page.locator('div:nth-of-type(2) > .col-md-9.display-value.ng-binding').textContent;
//Navigate to a different screen which now will display the trade number
await this.page.click('a[caption="History"]')
await this.page.click('a[href="#/trade-summary"]')
//Line of code that I am not sure how to correctly write. ".bidconfirmation" is the locator on the new screen which displays the trade number.
//If the contents or value of ".bidconfirmation" is NOT 1234 then an error needs to display.
await expect(tradeNumber).toHaveCSS('.bidconfirmation', tradeNumber);
}
Just to let you know I would change the tag on this post to playwright-JavaScript to better reach the intended audience.
However, if I understand your question correctly you are trying to get the text content of an element but the textContent() method is not working, I would try to use the innerText() method and see if that works.
Apologies if this is a little off as I work with the java version of Playwright but you could do:
const tradeNumber = page.locator('div:nth-of-type(2) > .col-md-9.display-value.ng-binding').innerText(); //BTW I would change this locator to something unique or a little more stable -- this should give you the tradeNumber
//then I'm not 100% sure what your trying to do here but if I understand correctly this might help
await expect(page.locator('.bidconfirmation').toHaveValue(tradeNumber));
I hope this helped a little, Im sorry I couldn't really get an understanding fully of the question you were asking but feel free to take a look at playwright.dev to find documentation surrounding Playwright.

locate displayed element with webdriverio

When developing in the Ionic framework, the generated html sometimes will contain duplicate DOM elements, where all but one tree of elements is hidden with a class="ion-page-hidden" at the top level.
When using webdriverio to try and locate an element inside this tree, it find duplicated elements. Since the ion-page-hidden class is at the top of the tree, and not on the element itself, how can we use Xpath to locate only the displayed element.
I couldn't figure out any way to modify the XPath selector with a second condition since the elements are exactly the same!
So instead I have tried to use the webdriverio isDisplayed() function:
get openHamburgerMenu() { return Utils.visibleElement($$("//ion-button[#name='button-open-menu']")); }
where the Utils function is:
async visibleElement(elementArray) {
let returnElement;
elementArray.forEach(element => {
if (element.isDisplayed()) {
returnElement = element;
}
});
return returnElement;
}
but no elements are passed into the function. In the chrome browser, I can see two that match the xpath //ion-button[#name='button-open-menu']. I need the one not in the ion-page-hidden block!
tree
The tree looks like this:
app-for-homes[1]/ion-header/ion-toolbar/ion-buttons[1]/ion-button
app-for-homes[2]/ion-header/ion-toolbar/ion-buttons[1]/ion-button
where app-for-homes[2] happens to have the ion-page-hidden class.
I think it should be possible to use ancestors to identify which of the two elements, matching the xpath, does not have a 4th level ancestor with that class? But I'm way out of my depth on day one of working with xpaths...
Quick and Dirty
The desired outcome can be achieved using this Xpath:
//app-for-homes[1]/ion-header/ion-toolbar/ion-buttons/ion-button[#name='button-open-menu']
However, this only works where the order in which the elements appears is known.
Better Answer
When you have exactly 1 element that is not hidden, Xpaths allow you to look at an elements ancestors as far back as you want to identify the presence / or absence of the hidden class. In this case, we start by finding the ancestor app-for-homes which does not include the ion-page-hidden class:
//app-for-homes[not(contains(#class,'ion-page-hidden'))]
and then simply append the remainder of the path to the desired element. Full answer =
//app-for-homes[not(contains(#class,'ion-page-hidden'))]/ion-header/ion-toolbar/ion-buttons/ion-button[#name='button-open-menu']

i am not able find dynamic element in android app

i have dynamic elements in my android app and there is nothing to find it out .Please check screen shot of my app and attributes and let me how can we do it.
I have tried with the given attributes
I just want ti find these elements and send keys
Try find element by xpath with this value:
//*[contains(#class,'android.widget.EditText')]
It will return the first element if there are many elements with same class.
If you want other element with class EditText, you can add count like this:
(//*[contains(#class,'android.widget.EditText')])[2]
The above for second element.
I tried this way of finding element:
List name = driver.findElements(By.xpath("android.widget.EditText"));
name.get(0).click();
But i am getting bellow error:-
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
Please let me know what is the issue?
I found one of my dynamic element through this method :-
findElementByXPath("//android.widget.FrameLayout[#index='0']/android.widget.EditText[#index='0']")
but for second element also , these details are same, so if i am putting same method to find second element , it search the first one only.
Than i printed size of the element with this find method
Size is coming like this
(996, 89)
Please let me know how can i find second element , because it has same details.

How to solve duplicate output by using search bar in ionic 4

I am using ionic 4. I want to do search function in my apps. I am using search bar and get the result from API.
My problem is it always output duplicate result.
One problem is I haven't typing the word finish it already match the result that I want to search, then it will output the result.
Another problem is when I finish typing it output again the result.
How can I solved or avoid this problem?
Here is my html code:
<ion-searchbar [(ngModel)]="name" (ionCancel)="onCancel($event)" (ionChange)="Search($event)"></ion-searchbar>
Here is my home.page.ts
Search() {
this.myService.getSearch(this.name);
}
The second one sounds like you are not wiping the data in your this.myService.getSearch call - check what it does in there, is it starting from a new list or just returning more results? If that doesn't solve that issue then post the code for that section.
The first issue is by design.
You can slow this down with the debounce option:
<ion-searchbar debounce="1500"></ion-searchbar>
There are two input events you can experiment with ionChange and ionInput - they act differently but I cannot remember exactly which does which, you will have to try them both. A third option would be to handle neither of them and just use a submit button.

Selenium *ElementPresent and *XpathCount give different results?

I am getting different results for the same locator. For example
//table[#id='foo']
returns true when testing ElementPresent, but returns 0 for XpathCount. In Selenium v1.0.10 IDE the Find button highlights the correct element for both functions. Any ideas on what could be causing this?
Notes:
We have frames on the page EDIT: This is probably the problem. Bounty to verification.
There are many tables on the page, but only one with #id of "foo"
Firefox 3.6
Happens in both IDE and Java RC
Well, this is not a verification more of a non-verification.
I use Selenium to test a GUI with frames. To make isElementPresent and getXpathCount to work I always have to select a frame first with selectFrame (even to get isElementPresent to work correctly). By just opening an URL no frame at all seems to be selected.
This is what the HTML and corresponding selectFrame code looks like:
<frameset id="mainframeset"><frame name="nav" id="nav" src....
selenium.selectFrame("nav");
Use these XPath expressions:
boolean(//table[#id='foo'])
and
count(//table[#id='foo'])
In case there is a table element whose id attribute's value is "foo", then the first expression above should evalute to true() and the second expression above should evalute to a positive integer.
Not really a direct answer to the question, but a workaround if you are reading this and want to loop over the elements. Use isElementPresent in the for loop like this:
for(int i = 2; selenium.isElementPresent("//table[#id='foo']//tr["+i+"]"); i++)
{
selenium.getText("//table[#id='foo']//tr["+i+"]//td["+columnNum+"]");
}
Note that we start i at 2 since XPath is indexed from 1 and we want to skip the header