← Back to team overview

schooltool-developers team mailing list archive

Printing self-closing tags in stests

 

[warning: tl;dr]

I'm working on new selenium tests and found an issue wanting to print elements containing self-closing tags. In our access rights page we have markup like (I've used ... to shorten some outputs):

----- %< -----
<span class="option">
  <label for="on.persons_can_change_their_passwords">
    <input ... />
    <span class="label">...</span>
  </label>
</span>
<span class="option">
  <label for="off.persons_can_change_their_passwords">
    <input ... />
    <span class="label">...</span>
  </label>
</span>
----- %< -----

So I was trying to print the <label> elements using (btw, I've got addicted to css3 selectors now, die xpath! :D):

>>> css_selector = 'label[for$=".persons_can_change_their_passwords"]'
>>> manager.printHTML(manager.query_all.css(css_selector))

and I got:

<label for="on.persons_can_change_their_passwords">
  <input ...>
    <span class="label">
      ...
    </span>
  </input>
</label>
<label for="off.persons_can_change_their_passwords">
  <input ...>
    <span class="label">
      ...
    </span>
  </input>
</label>

Note the <input> surrounding the <span>. So, I started to dig and got first to schooltool.testing.selenium.getWebElementHTML (which btw was missing the driver argument in the recursive call to itself). I noticed getWebElementHTML was producing:

<label for="on.persons_can_change_their_passwords">
  <input ...>
  <span class="label">Users can change their own passwords.</span>
</label>

<input ...> misses the closing "/>" here, as a result of calling innerHTML on the driver. I couldn't find a way to make innerHTML to spit the '/>' other than using search/replace.

This html is next passed to the schooltool.testing.selenium.HTMLSerializer, which finally produces the <input>...</input> representation. Unfortunately, at this point we cannot parse the string as XML anymore.

HTMLSerializer.print_tag seems to try to insert the '/>' on empty elements, but in this case the parsing phase has already created an element inside the <input>...</input>.

In the meantime, I'm going to use selectors to get to the <input ... /> elements directly:

>>> css_selector = 'input[id$=".persons_can_change_their_passwords"]'
>>> manager.printHTML(manager.query_all.css(css_selector))

which produces:

<input ... />
<input ... />

but I think the current behaviour is kind of annoying. Just my $0.02 :)

Douglas

"... allí­ es cuando te das cuenta que las cosas malas pueden resultar bastante buenas..." - Lionel Messi

Por favor, evite enviarme adjuntos de Word, Excel o PowerPoint.
Vea http://www.gnu.org/philosophy/no-word-attachments.es.html