How to use a css selector wildcard if the id values keep changing - selenium

How to use a css selector wildcard if the id values keep changing?
<td role="gridcell" style="text-align:center;" title="**Edit** | Copy</a" aria-describedby="list4_action">Edit | Copy</td>
This is in a table where the id # 12374 changes for every new row . I was looking for selenium to click the EDIT button .
When i use cssSelector:a[href*='/mac1/notication/edit?$id='*] the test is failing with the message
Caused by: org.openqa.selenium.InvalidSelectorException: The given selector a[href*='/mac/notication/edit?$id='*] is either invalid or does not result in a WebElement. The following error occurred:
InvalidSelectorError: An invalid or illegal selector was specified

You are correct in using the CSS3 [attribute*=value] Selector.
However, you have a typo in your CSS Selector (you spelled notification wrong) and you've included an unnecessary $ character. Try this:
a[href*='/mac1/notification/edit?id=']
Essentially, this CSS Selector will search for an <a> tag with an href attribute containing the string /mac1/notification/edit?id=.

Try with the following CSS selector,
 
a[href^='/mac1/notification/edit?id=']

This was a little tricky as the UI page and table were coded differently.
Hence had look for the value of the JQGrid since it is a table. Then check for the value 'Edit' in the table and the pass the Click id. The id I was using was the correct one except that just using that id was not working.
The id that was used was alert.edit=cssSelector:a[href*='/mac1/Notification/edit?id=']

Related

Can the By strategy tagName be replaced with cssSelector for the same value?

I replaced the locator tagName with cssselector without changing the arguments and the code still worked perfectly.
The previous script was:
Driver.findElement(By.tagName("*enter tagName*");
Replacement code is:
Driver.findElement(By.cssSelector("*enter tagName*");
The code worked despite the fact that I did not use any cssSelector combination.
How is that possible?
This worked correctly since tag name alone is a correct CSS Selector.
Generally CSS Selector is may look like the following: tagName[attributeName='attributeValue'] where you can omit the attribute name and value and locate the element based on tagName only. So tagName lonely will still be a correct CSS Selector.
By.TAG_NAME is always equivalent to By.CSS_SELECTOR
As per the definition of find_element():
elif by == By.TAG_NAME:
by = By.CSS_SELECTOR
Hence the previous line of code:
Driver.findElement(By.tagName("enter tagName");
and the replacement line of code:
Driver.findElement(By.cssSelector("enter tagName");
was equivalent.

behat fillField xpath giving error?

This line of code:
$this->fillField('xpath','//fieldset[#id="address-container"]/input[#name="address_add[0][city]"]', "Toronto");
Is giving me this error
Form field with id|name|label|value|placeholder "xpath" not found. (Behat\Mink\Exception\ElementNotFoundException)
The reason I want to use xpath in my fillField is because there are actually multiple input[#name="address_add[0][city]"] in my html document. I figure an xpath will let me target specifically the field I want to populate.
What's the best way to fill out just the input[#name="address_add[0][city]"] that is a descendant of fieldset[#id="address-container"] ?
You are not using the method in the wright way.
As i see here xpath is taken as selector.
The method expects 2 parameters:
identifier - value of one of attributes 'id|name|label|value'
value - the string you need to set as value
If you want to use css|xpath then you need to use find method first.
For example:
$this->find('xpath', 'your_selector')->setValue('your_string');
Please note that find might return null and using setValue will result in a fatal exception.
You should have something like this:
$field = find('xpath', 'your_selector');
if ($field === null) {
// throw exception
}
$field->setValue('your_string');
Also your selector could be written as:
#address-container input[name*=city] - this with css
or
//fieldset[#id="address-container"]//input[contains(#name, 'city')] - this with xpath
Make sure you take advantage of your IDE editor when you have any doubts using a method and you should find a php doc with what parameters are expected and what the method will return.
If you are using css/xpath a lot you could override find method to detect automatically the type of selector and to use it like $this->find($selector);
Also you could define another method to wait for the element and to handle the exception in one place, for example waitForElement($selector) that could contain a conditional wait up to 10 seconds and that throws exception if not found.

How to select the element in HTML tags based on its text in Behat?

I'm running the following Behat scenario:
Then I should see "Testing body" in the "strong" element
for the following HTML snippet:
<strong>Testing body</strong>
However I am getting an error:
The text "Testing body" was not found in the text of the element matching css "strong"
What is the best way to check if element contains below tags?
<em>Testing body</em>
<ol><li>Testing body</li>
</ol>
<ul><li>Testing body​​​​​​​</li>
</ul>
I am trying to use wysiwyg.feature with syntax:
Then I should see "Testing body" in the "<Element>" element with the "<Property>" CSS property set to "<Value>" in the "Pearson Content" region
Make sure the selector used is unique.
Depending on the method used you might need id|name|label|value or css selector.
I your case the selector used is too general, you need to narrow the section by adding an extra element in front of this to tell him to search in a smaller section.
For example: #myid strong -> will search strong in the element that has the id myid
Same thing for the other elements, you could have ol>li or ul>li, but if more elements are found you will need to add an extra selector in front to narrow the section.
Always check the CSS manually in the browser and make sure is unique or the element that you need is found first.
If you want to check for an element that contains some text, you could use XPath like this:
//strong[contains(text(), 'Testing body')]
You can also use a css if you can identify this section as I said above, but I need more from the html, a large section in order to get a better selector.
The following method may help:
/**
* #Given I should see :text in the :tag element
*/
public function iShouldSeeInTheElement($text, $tag) {
$this->verifyElementByXpath("//${tag}[contains(text(), '${text}')]");
}
Instead of contains, you can also use starts-with and other.
Note: I haven't tested it, so please suggest improvements if you do.

WebDriverException Element must be user-editable in order to clear it

I am trying to run test cases to perform reset password and I am facing this issue.
WebDriverException Element must be user-editable in order to clear it.
Basically i am accessing the page for entering the new password and doing this:
browser.$("#newPassword").text("password");
where execution of the above line throws the error.
I had the same problem and it was because there was another element with the same id which was not an input field so it could not be cleared.
We can try the following:
WebElement.sendKeys(Keys.DELETE);
WebElement.sendKeys("Test");
It might be a case of using the wrong method for the input type.
In CodeCeption at least, fillField should be used on input elements and selectOption should be used on select elements and mixing them up will give invalid element state: Element must be user-editable in order to clear it.
I had this problem with a Primefaces autoComplete element. Primefaces 6.0 renders a span with the ID you pass, and within that an input with a "_input" appended to the ID. If you just use the ID you added in your source code, you tell Selenium to enter into the span (which fails with the "element must be user-editable" error). Add the "_input" to the ID if you select by ID in selenium.

Select element A or element B with CSS selector

Is there a way to select either one of the 2 elements specified in CSS selector expression? If element A is not found then select element B.
Example:
css=input[id$=sometext]#id OR textarea[id$=sometext]#id
The above expression should return id of either input element or textarea element whose id ends with "sometext".
As a side note, I'm trying to use this CSS selector in selenium2library which uses sizzle for handling css selectors.
I tried the following approaches, none of them seem to work (syntax error):
css=input[id$=sometext]#id / textarea[id$=sometext]#id
css=input[id$=sometext]#id/textarea[id$=sometext]#id
css=input[id$=sometext]#id/css=textarea[id$=sometext]#id
css=input[id$=sometext]#id OR css=textarea[id$=sometext]#id
css=input|textarea[id$=sometext]#id
css=input[id$=sometext]#id, textarea[id$=sometext]#id
css=input[id$=sometext]#id,textarea[id$=sometext]#id
Sizzle uses CSS selectors, and, for example, #id is not a CSS selector. I'm personally not sure what #id is supposed to mean, but, without that part, try:
input[id$=sometext],textarea[id$=sometext]