I have a Calendar table which shows both enabled and disabled dates. I want to be be able to select day 30 from the table which is not disabled. How do I select just this element to click on?
<table >
<tbody>
<!-- ko foreach: calendarRows.weeks -->
<tr data-bind="foreach: days">
<td data-bind="css: { disabled: disabled, selected: selected }, click: select, event: {keypress: select}" >
<span data-bind="text: dayNumber" tabindex="0">30</span>
</td>
</tr>
<tr data-bind="foreach: days">
<td data-bind="css: { disabled: disabled, selected: selected }, click: select, event: {keypress: select}" >
<span data-bind="text: dayNumber" tabindex="0">30</span>
</td>
</tr>
<!-- /ko -->
</tbody>
</table>
Original XPATH which failed when two 30's were displayed was:
//span[contains(@class,'day-number')][(text()='" day "')]
Tried:
.//td[(@class='calendar-day') and not(@class='disabled')]/span[contains(@class,'day-number')][(text()='" day "')]
But no luck.
What am I doing wrong? Assistance greatly appreciated.
CodePudding user response:
Neither td element has a class that is equal to exactly the text “disabled”, and your second xpath expression is asking for the class to not be equal to disabled. And because both do not equal “disabled” they are both returned. That is, the expression not(@class='disabled')
is evaluating if the class attribute text value is not exactly equal to the text “disabled”.
In xpath, the attribute “class” is treated like any other attribute and doesn’t look for class names, just the full value of the attribute. It is not aware of the meaning of the class attribute in html and css rendering and is just trying to match the full value “calendar-day disabled” to your expression.
Thus you want to build an expression for “does not contain” the text “disabled”. The same for checking if the class contains “calendar-day”. In this specific and limited case this works, but note that “contains()” is a substring match so it may not work as intended if there could be other class names that partially contain your search string, such as “disabledPreviously”.
Here’s an example of doing a not contains (it doesn’t use the class attribute specifically but still an example of doing not contains).
https://stackoverflow.com/a/11024134/2346994
CodePudding user response:
Thanks for the input. The answer to this problem was:-
.//td[not(contains(@class,'disabled'))]/span[contains(@class,'day-number')][(text()='" day "')]