0
votes

I am having a little problem with xpath in seleniumdriver.

I would like an xpath locator to narrow down its selection via two variables using exact matching at different points of the node hiearchy. This part is done.

You may imagine my case as addressing a two dimensional array in the xml with xPath, with each dimension being given as the two variables I have in it(they are standard text searches via js variables, not xpath variables).

What I'm struggling with is the resulting construction does not tell the difference between the elements of the first dimension, so as long as the given variable value is one of the dimensions, it will address every element in the second dimension fine. I can not assume they are unique or they are in any order. I am using it for testing so this is not acceptable.

How can I form an expression that will not doesn't do the same mistake? I have tried the 'and' expression but both selenium and xpath tools say the value is '1' for 'found' but it doesn't give me a node locator to work with.

Example, my structure looks similar, so addressing it properly by x1/y1 for example looks fine.

//x1//y1
//x1//y2 
//x2//y3 
//x2//y4 
//x3//y5 
//x3//y6

Should work, works ok.

//x1x//y1
//x1x//y2
//x2x//y3
//x2x//y4
//x3x//y5
//x3x//y6

(Giving nonexistent input as 1st dimension.) My input is not fault tolerant, I look for exact value so the tests fail here as they should.

//x2//y1
//x2//y2
//x3//y3
//x3//y4
//x1//y5
//x1//y6

DING, the locator finds y values here when it should not(the y vales are on different leaves of the node tree). I need help with this.

Here is the locator in question:

return element(by.xpath(".//div[@name='typeList']//div[.//text()='" + moduleName + "']//div[./text()='" + typeName + "']")).getText();

TypeList is the name of the owner element, it does not make any differnece if I remove it, but please keep it in mind when giving me examples.

1
Your structure confuses me. I first thought that x and y where tags, but in your XPath you are looking for text. Do you know which one it finds? - cvesters
Let me put in an other way. I am testing to verify the 'files' are in their correct 'directories'. x values in example are directories and y are the files. I find the correct elements via their text value, through the variables. The x and y themselves are just examples. They are not tags, they represent possible values for my text search variables. - hardcore
Yes I know which element is found. - hardcore
Is it possible to give link to the webpage or provide html - Madhan
Not possible, its an internal company page under development. I will reword and ask the question again in a few hours with a simple example html I will write as it seems more confusing than it is. It's all about the first text search part of the expression not applying the filter to the later nodes at it should. - hardcore

1 Answers

0
votes

In the end, it was indeed a syntactical problem, before the text keywords.

I was trying this

//div[./text()='Zero']//div[./text()='Number']

Instead, I needed something like this.

//div[.//text()='Zero']/div[.//text()='Number']

Apparently the first one does looks for 'Number' regardless the value of the first constraint as long as every is defined in my file(does not have to be in its upward xnode path.)

As a final note, I advise against using the chrome xpath helper as its behavior is near random, it gives different results after deleting and replacing the same expression. Ugh. The only other one for chrome is adware... I figured my result out by trial and error with the firefox xpath checker tool.

1, I ended up needing to additionally add an node upwards for the element for angular select ui tool(we use selectize.js, a searchable select box), else it was confused what to return, but this is unrelated to the original question as I tried that before with the original expression.

2, I also had to add a node between the first and second text search, else it would look for the second expression in the first one too, eg. looking for Number in Zero, and treat it like a valid value if found. The problem still occurs the other way around, this can be fixed too by applying additional type/name constraints in the first one(not in final example to save space).

So this is what I ended up with:

.//div[@name='typeList']//div/div[.//text()='Zero']/div/div/div[.//text()='Number']