How to use not() in conjunction with 'and' in xpath - xpath

I have a scenario where I should select only those elements with color other than rgb(170, 170, 170).
I'm trying to locate elements with the following xpath:
.//span[#class='box' and not(#style='background-color: rgb(170, 170, 170)')]
With this xpath firebug is selecting all of the elements including those I restricted with the not().

Most likely (as kjhughes pointed out) does you style attribute contain more styles than the background-color. To find your value any way you may use contains().
(contains(#style,, 'background-color: rgb( 170, 170, 170)')
But now the formating may still have different amount of spaces.
To avoid them you can use translate() To remove all spaces use:
translate(#style,' ','')
Therefore try:
//span[#class='box' and not(contains(translate(#style,' ',''), 'background-color:rgb(170,170,170)') )]

Related

How to get multiple elements with data-cy attributes

I have a table with all cells marked with the data-cy attribute as so: [data-cy="cell-${row}-${column}].
Individually I have no trouble to get each cell with the classic cy.get, for example cy.get("[data-cy=cell-2-17]").click(), but I try to test the click on multiple cells holding the control key but I couldn't achieve that.
In this answer it says to simply concat the selectors passed to cy.get but it didn't work for me, I tried with and without the " around the data-cy names:
cy.get('[data-cy="cell-2-17"][data-cy="cell-4-10"]').click({multiple: true, ctrlKey: true})`
Could you tell me how to get multiple elements using the data-cy attribute?
If you concatenate selectors (without space or + between), it means the element must have all those selectors.
There's not really a concise way to provide a list of required attributes.
Two things that help are wildcards and filters
const cellsWanted = ['cell-2-17', 'cell-4-10']
cy.get('[data-cy^="cell-"]') // wildcard anything that starts with "cell-"
.filter((index, el) => cellsWanted.some(cell => el.getAttribute('data-cy') === cell))
.click({multiple: true, ctrlKey: true})`
Multiple selectors with comma between
Just found an easier way using jquery multiple selectors
cy.get('[data-cy="cell-2-17"], [data-cy="cell-4-10"]')
.should('have.length', 2)
.click({multiple: true, ctrlKey: true})

using an expression to show or hide rectangle based on a parameter value (SSRS)

Trying to show/hide a couple of rectangles in SSRS based on an expression which uses the value of a parameter in the report. See the screenshots for more details. When the '-Cover pages' label is picked I want it to display the rectangle but I consistently get the following errors. It can't seem to convert and read the parameter expression no matter what I do.
The expression I'm trying to use is:
=iif(Parameters!specparam.Value="-Cover Pages",true,false)
It looks like the label of your parameter is what you're looking for based on the image provided and your expression. Try to switch instead to:
=IIF(Parameters!specparam.Label="-Cover Pages",TRUE,FALSE)
(Note: I switched specparam.Value to specparam.Label.
Your comment is very close. Apply this expression to the Hidden property of the rectangle:
=IIF( Parameters!specparam.Label.Equals("-Cover Pages"), FALSE, TRUE )
You'll notice I have switched around the FALSE and TRUE as you don't want the rectangle to hide when the parameter matches.
Edit:
As you're dealing with a multivalue parameter, you can use a combination of Array.IndexOf and Split to check if your value is one of the selected parameters.
Apply this expression to the Hidden property of your rectangle:
=IIF( Array.IndexOf( Split( Parameters!specparam.Value, "," ), "-Cover Pages" ) > -1, FALSE, TRUE )

xpath expression to read value based on value of sibling

I've below xml and would like to read the value of 'Value' tag whose Name matches 'test2'. I'm using the below xpath , but did not work. Can someone help.
/*[ local-name()='OutputData']/*[ local-name()='OutputDataItem']/*[ local-name()='Name'][normalize-space(.) = 'test2']//*[local-name()='Value']/text()
<get:OutputData>
<get:OutputDataItem>
<get:Name>test1</get:Name>
<get:Value/>
</get:OutputDataItem>
<get:OutputDataItem>
<get:Name>test2</get:Name>
<get:Value>B5B4</get:Value>
</get:OutputDataItem>
<get:OutputDataItem>
<get:Name>test3</get:Name>
<get:Value/>
</get:OutputDataItem>
<get:OutputDataItem>
<get:Name>OP_VCscEncrptCd_VAR</get:Name>
<get:Value/>
</get:OutputDataItem>
</get:OutputData>
Thanks
You were close, but because the get:name and get:value are siblings, you need to adjust your XPath a little.
Your XPath was attempting to address get:value elements that were descendants of get:name, rather than as siblings. Move the criteria that is filtering the get:name into a predicate, then step down into the get:value:
/*[ local-name()='OutputData']/*[ local-name()='OutputDataItem']
[*[ local-name()='Name'][normalize-space(.) = 'test2']]/*[local-name()='Value']/text()
You could also combine the criteria of the predicate filter on the get:name and use an and:
/*[ local-name()='OutputData']/*[ local-name()='OutputDataItem']
[*[ local-name()='Name' and normalize-space(.) = 'test2']]/*[local-name()='Value']/text()
This should work I think:
//*[local-name()="get:Name" and text()="test2"]/following-sibling::*[local-name()="get:Value"]/text()

Finding xpath for an element loaded by Ajax-json response using class and text

I have an element like
<td class="google-visualization-table-th gradient google-visualization-table-sorthdr">
Project Name
<span class="google-visualization-table-sortind">▼</span>
</td>
I tried
driver.findElement(By.xpath("//td[contains(#class, 'google-visualization-table-th') and normalize-space(text()) = 'Project Name']")
But its not working. Basically its code for Column header and I need to recognize each column header and print if the heading exist or not.
We do not know which version of XPath you are using, but depending on the exact version, text() means different things.
I suspect that the text content of span(the weird character ▼) is also part of td/text(). This is because text() does not mean:
Return the rext nodes of the context node
In this case it means:
Return the text nodes of the context node and the text nodes of all its decendants.
Use contains() also in the second half of the predicate:
//td[contains(#class, 'google-visualization-table-th') and contains(.,'Project Name')]
Its resolved now, element was not getting identified because they were getting loaded in an iframe. I used the below code o switch to iframe and then did usual operations to track the elements.
WebDriverWait wait = new WebDriverWait(driver, 200);
By by = By.id("iframe id");
try {
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(by));
Thanks everyone for the help.

Selenium Webdriver + Ruby regex: Can I use regex with find_element?

I am trying to click an element that changes per each order like so
edit_div_123
edit_div_124
edit_div_xxx
xxx = any three numbers
I have tried using regex like so:
#driver.find_element(:css, "#edit_order_#{\d*} > div.submit > button[name=\"commit\"]").click
#driver.find_element(:xpath, "//*[(#id = "edit_order_#{\d*}")]//button").click
Is this possible? Any other ways of doing this?
You cannot use Regexp, like the other answers have indicated.
Instead, you can use a nifty CSS Selector trick:
#driver.find_element(:css, "[id^=\"edit_order_\"] > div.submit > button[name=\"commit\"]").click
Using:
^= indicates to find the element with the value beginning with your criteria.
*= says the criteria should be found anywhere within the element's value
$= indicates to find the element with with your criteria at the end of the value.
~= allows you to find the element based on a single criteria when the actual value has multiple space-seperated list of values.
Take a look at http://net.tutsplus.com/tutorials/html-css-techniques/the-30-css-selectors-you-must-memorize/ for some more info on other neat CSS tricks you should add to your utility belt!
You have no provided any html fragment that you are working on. Hence my answer is just based on the limited inputs provided your question.
I don't think WebDriver APIs support regex for locating elements. However, you can achieve what you want using just plain XPath as follows:
//*[starts-with(#id, 'edit_div_')]//button
Explanation: Above xpath will try to search all <button> nodes present under all elements whose id attribute starts with string edit_div_
In short, you can use starts-with() xpath function in order to match element with id format as edit_div_ followed by any number of characters
No, you can not.
But you should do something like this:
function hasClass(element, className) {
var re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)');
return re.test(element.className);
}
This worked for me
#driver.find_element(:xpath, "//a[contains(#href, 'person')]").click

Resources