Philll_t Philll_t - 3 months ago 27
HTML Question

Trying to grab a specific element with css selector

I'm using nightwatch.js and am trying to click a button on the date picker ui for jQuery. Obviously, depending on the day I'm going to run the test, the DatePicker UI changes.

I'm trying wrap my head around how I'm going to get nightwatchjs to click on the first non-disabled option (which jQueryUI presents as a link within a

td
element instead of a
span
).

<table class="ui-datepicker-calendar">
<thead>
<tr>
... Header
</tr>
</thead>

<tbody>
<tr>

... This entire row is disabled with td like this:

<td class=
"ui-datepicker-week-end ui-datepicker-unselectable ui-state-disabled class">
<span class="ui-state-default">6</span></td>
</tr>

<tr>
<td class=
"ui-datepicker-week-end ui-datepicker-unselectable ui-state-disabled class">
<span class="ui-state-default">7</span></td>

<td class="ui-datepicker-unselectable ui-state-disabled class"><span class=
"ui-state-default">8</span></td>

<td class="ui-datepicker-unselectable ui-state-disabled class"><span class=
"ui-state-default">9</span></td>

<td class="ui-datepicker-unselectable ui-state-disabled class"><span class=
"ui-state-default">10</span></td>

<td class=
"ui-datepicker-unselectable ui-state-disabled class ui-datepicker-today">
<span class="ui-state-default">11</span></td>

// First instance of a clickable button that has an "a" element in it and this is the only one I want to grab:

<td class="ui-datepicker-days-cell-over class" data-handler="selectDay"
data-event="click" data-month="7" data-year="2016"><a class="ui-state-default"
href="#">12</a></td>

<td class=
"ui-datepicker-week-end ui-datepicker-unselectable ui-state-disabled class">
<span class="ui-state-default">13</span></td>
</tr>

<tr>

... Another row
</tr>

<tr>
... Another row
</tr>

<tr>
... Another row
</tr>
</tbody>




So I've been playing with CSS to try and figure out what selector I can use to select the first
a
inside this table. I've tried these but it all grab the first
a
in the
td
because its the first child of that parent.

All of the following select all the links:

a:first-child
a:first-of-type
a:nth-child(1)
a:nth-of-type(1)


I've also tried a bit more specific:

.ui-datepicker-calendar tr td a:first-child
...


Still the same.

Any ideas?

Answer

After a few a hours of fiddling and research I realized that there wasn't an easy way of doing it using CSS selectors. Luckily Nightwatch.js allows you to use xPath.

You can easily switch between css or xpath. The following code works perfectly:

     ...
      .useXpath() // Switch to xPath
      .click('(//div[@id="ui-datepicker-div"]/table[@class="ui-datepicker-calendar"]/tbody/tr/td/a)[1]')
      .useCss() // then back to css
     ...

xPath provides a much richer, though a bit more complicated, method of selection. This was a perfect example of how using xPath is far more better than using the css selector.

Learn more about xPath here or here.

Learn how nightwatch.js uses xPath here.