Downwards compatibility, and a surprising find
I've just released a new version of
WWW::Mechanize::Firefox, appropriating a new function of
->click_button. I used that occassion to also change the XPath queries sent by W:M:F to Firefox to be somewhat slimmer by changing queries for the element type from a global "OR" to a local test for the node name:
The old query to look for a
<INPUT type="submit"> was
//button | //input[@type = "submit" ]
The new query is
//*[local-name(.) = "button" or (local-name(.) = "input" and @type="submit")]
The advantage of the new type is that the query engine does not need to search the DOM tree twice, and more importantly, that I can now easily ask for the "third button in this form", which I cannot do with two separate queries, as they don't necessarily return the buttons in the relative order in which they appear in the HTML+DOM.
All would be well if it weren't for differing Firefox versions.
local-name(.) returns the element name. Except that in versions before 3.6, the element name for HTML pages is in ALL UPPERCASE, while since 3.6 onwards, it is in lower case. Of course, this is no real hindrance, as we can just
lower-case() the element name. Except that Firefox does not implement
lower-case(). It only implements
translate(), which is uneasily similar to the
tr/// operator in Perl. As you can imagine in your horror-filled dreams, the generated queries now look like this:
//*[translate(local-name(.), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")="button" or (translate(local-name(.), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")="input" and @type="submit")]
... at least until I ditch support for older Firefox versions.
While I was copying the test suite of
click_button.t, I saw that it launches a local HTTP server to test against that. Digging deeper, I found that it actually and actively uses a server that I once wrote to test
WWW::Mechanize::Shell. This has really surprised me and made me happy. If people don't use my modules, at least my test infrastructure gets used by other modules in the same problem space, so I must do something right.