Puppeteer finds selector locally but not on heroku - heroku

I have a weird error whereby puppeteer finds a selector locally but not when run in Heroku.
I click on a select search box which then reveals a list of select items, but for some reason puppeteer is able to find all selectors in the list except for the last one, only when run on Heroku. It finds all selectors when run locally.
I've tried waiting for the selector but that still doesn't help, it just cannot seem to find it. It works for other accounts that have a longer list of items.
error: failed to parse stock level page { TimeoutError: waiting for selector "#siteList_chosen > div > ul > li:nth-child(19)" failed: timeout
so in the image below, the selector fails to find data-option-array-index="18"

To find selector like this you can use:
[data-option-array-index="18"]
instead of
li:nth-child()
Also you can use less strict selector to get all elements like this:
await page.$$('.chosen-results li')
this will get all li elements - then you can iterate over this using .forEach (but first you need to convert NodeList to Array).

Related

Cypress xpath plugin does not work with cy.type()

I am unable to figure out why the cypress xpath is not working with the type(). I have two command functions: one that looks for the element using cy.get() and one that uses cy.xpath(). Unfortunately, this is a dynamic field so I have to use xpath.
(https://i.stack.imgur.com/wXl9q.png)
This is how I am using the above command.
(https://i.stack.imgur.com/snVn7.png)
Error:
(https://i.stack.imgur.com/08G32.png)
I tried to reading the cypress docs and searching on the internet, however the examples for solutions did not work. I am on on Electron version: 21.0.0, Bundled Node version:
16.16.0
I think you are mistaken about the results of your xpath expression.
You have used //div[5]/div[1]/input which can return multiple elements.
The // predicate will "select all" if they are present.
Only / predicate is guaranteed to return a single element.
Since Cypress is telling you it found multiple elements, it is more likely that your selector is wrong than the Cypress library.
You will have to change the xpath selector.
The answer is in your error message - you're trying to use cy.type() but the previous command (cy.xpath()) is yielding more than one element. I would focus on figuring out what differentiates the field you want to type in from the others found by cy.xpath(). If there is nothing different between them, then you can simply select the correct element by the 0-index of the element.
cy.xpath(element).eq(0).type(value); // assumes the first element yielded by cy.xpath

Is it possible to wait for two Web Elements at the same time in Robot Framework via Xpath?

I have two Web Elements and if one of them appears it should trigger a keyword.
But i dont find anything in the web to connect a logical operation like OR/AND into my XPATH...
Is there a possible workaround??
Wait Until Element Is Visible ||| //body/div[#id='app']/div[${count1}]/div[${count2+2}
but the trigger shoud be
${count2+2} OR ${count2+1}
Before anything else: this is not a question of Robot Framework but on how to work with xpath and identify elements in the page.
So if you want to search 1 div or another div, just find the "thing" that clearly identify each and then:
//div[#this='first' or #that='second']
If the elements are in different nodes/levels, you can always do:
(//div[#this='first']) | (//div[#that='second'])

How can I get Watir to make a fresh reference on a non-stale element?

A portion of some tests I am writing calls for checking if an option gets removed from a select list once that option has been used. I am inconsistently getting this error: timed out after 60 seconds, waiting for {:xpath=>"//select[#id = 'newIdentifierType']//option", :index=>31} to be located (Watir::Exception::UnknownObjectException)
It causes my test to fail maybe 2-3 times out of 10 runs and seems kind of random. I think Watir is looking for the "old" select list with this ID since it caches the element and may also include that it had 32 items, but it times out since a select list with this ID and 32 items no longer exists. The new select list has the same ID but only 31 items.
Is there a way to always get a new reference on this element even though it's not technically going stale? Am I experiencing this problem due to a different issue?
My current code for getting the options in the select list:
#browser.elements(:xpath => "//select[#id = 'newIdentifierType']//option")
I am using Ruby/Cucumber with Selenium and Watir Webdriver level. I first tried defining the element as a select_list in a page-object but moved it to the step definitions using #browser.element to see if that would stop the timeout. I thought it may ignore Watir's cached elements and get the most current one with the ID, but that does not appear to be the case.
Please avoid using XPath with Watir. Everything you can do with XPath, Watir has a much more readable API to handle.
To check for a specific option not being there, you should avoid collections and locate directly:
el = browser.select_list(id: "newIdentifierType").option(value: "31"))
# or
el = browser.select_list(id: "newIdentifierType").option(text: "This one"))
Then to see if it has gone away:
el.stale?
# or
el.wait_until(:stale?)
That won't test the right thing if the entire DOM has changed, though, so you might need to just relocate:
browser.select_list(id: "newIdentifierType").option(text: "This one")).present?
If you are intent on using a collection, the correct way to get the list of options is:
options = #browser.select(id: 'newIdentifierType').options
el = options.find { |o| o.text == 'This one' }
# Do things
el.stale?

How to handle variable xpath of element(xpath keep changes) in selenium webdriver

I am trying to locate Ajax control (mouse over) on Amazon home page for sign in.
WebElement element = driver.findElement(By.xpath("//*[#id='nav-link-yourAccount']"));
however this element locator works for some time and other times its not finding element and script is failing.
I have noticed that Xpath of this element is changing sometimes to //*[#id='nav-link-yourAccount']/span[1], there is no any other unique identifier which can be used to locate this element.
Could you please let me know how to resolve this variable xpath issue.
If you fail to find an element at one of the xpath values, you could try searching for the other xpath value. You could use ExpectedConditions to wait for a certain period of time for an element to exist. If that time elapses and the element is not found, then use the second locator to find the element. This assumes that the xpath is only changing between these two known values. Also, once you locate the element, you might want to make some assertions about the other properties of the element to further ensure you've found the element you're looking for.
Here's a post about waiting for an element:
Equivalent of waitForVisible/waitForElementPresent in Selenium WebDriver tests using Java?

getting attribute via xpath query succesfull in browser, but not in Robot Framework

I have a certain XPATH-query which I use to get the height from a certain HTML-element which returns me perfectly the desired value when I execute it in Chrome via the XPath Helper-plugin.
//*/div[#class="BarChart"]/*[name()="svg"]/*[name()="svg"]/*[name()="g"]/*[name()="rect" and #class="bar bar1"]/#height
However, when I use the same query via the Get Element Attribute-keyword in the Robot Framework
Get Element Attribute//*/div[#class="BarChart"]/*[name()="svg"]/*[name()="svg"]/*[name()="g"]/*[name()="rect" and #class="bar bar1"]/#height
... then I got an InvalidSelectorException about this XPATH.
InvalidSelectorException: Message: u'invalid selector: Unable to locate an
element with the xpath expression `//*/div[#class="BarChart"]/*[name()="svg"]/*
[name()="svg"]/*[name()="g"]/*[name()="rect" and #class="bar bar1"]/`
So, the Robot Framework or Selenium removed the #-sign and everything after it. I thought it was an escape -problem and added and removed some slashes before the #height, but unsuccessful. I also tried to encapsulate the result of this query in the string()-command but this was also unsuccessful.
Does somebody has an idea to prevent my XPATH-query from getting broken?
It looks like you can't include the attribute axis in the XPath itself when you're using Robot. You need to retrieve the element by XPath, and then specify the attribute name outside that. It seems like the syntax is something like this:
Get Element Attribute xpath=(//*/div[#class="BarChart"]/*[name()="svg"]/*[name()="svg"]/*[name()="g"]/*[name()="rect" and #class="bar bar1"])#height
or perhaps (I've never used Robot):
Get Element Attribute xpath=(//*/div[#class="BarChart"]/*[name()="svg"]/*[name()="svg"]/*[name()="g"]/*[name()="rect" and #class="bar bar1"])[1]#height
This documentation says
attribute_locator consists of element locator followed by an # sign and attribute name, for example "element_id#class".
so I think what I've posted above is on the right track.
You are correct in your observation that the keyword seems to removes everything after the final #. More correctly, it uses the # to separate the element locator from the attribute name, and does this by splitting the string at that final # character.
No amount of escaping will solve the problem as the code isn't doing any parsing at this point. This is the exact code (as of this writing...) that performs that operation:
def _parse_attribute_locator(self, attribute_locator):
parts = attribute_locator.rpartition('#')
...
The simple solution is to drop that trailing slash, so your xpath will look like this:
//*/div[#class="BarChart"]/... and #class="bar bar1"]#height`

Resources