Well Live an Learn

Well one of those days again,


well not that bad just a little frustrating and not very productive for about 3 hours of time.

Was playing about with Test-WWW-Selenium and going at it great guns after about a four year absence since I had to use Test::WWW::Mechanize in the last place I worked that was doing a little testing, Needless to say I was just a little rusty in my Selenium skills and I didn't have my code base from when I used it last but I was glad to see one can get the Selenium server running headless on ubuntu.

So I get into the programming swing of things and the I get stuck. I have to test all the links on a page to make sure there are no bad ones. So easy I remeber how to do that just

my @links = $agent->get_all_links();
and to my surprise when I dump the @links I get


Going down for about 300+ empty links. Ah yes just the ID are returned (forgot about that) so I had a look at the raw html and

<li id="ui-gen3" class="uimenuitem" groupindex="0" index="2">
<a class="uimenuitemlabel" href="***">Some Link</a>

so no ids on any of the links. Curses.

Well I wasn't about to add in the id on many hundreds of A tags as that only solves halve my problem as I did a little more poking about and I found ID where very few and far between in this code base. Oh well add in a project for that. (Bring HTML code up to early 2000s standard)

So undaunted I spend the rest of my day trying to figure a way to get my links out.

I know I can get a count of an element like this

 my $count = $sel->get_xpath_count('//a');

They I could just loop through them like this and lift the href attribute from each.

 foreach my $index (1..$count){
    my $href = $sel->get_attribute("//a[$index]\@href"));

well no luck there at that really only work when you have nested nodes so I went 1 higher with


still getting the same count but now getting only a a few links when I do the loop

foreach my $index (1..$count){
    my $href = $sel->get_attribute("//li[$index]\a\@href"));

and then it would die after about 9. Looking at the end results I finally figured out it was giving me this


and would die on 10 as I did not have a 'A' tag next to a 'LI' tag nested 10 deep.

Well after attempting I think every possible xpath combination I was about to give up and head back to Mechanize (though without JS it would cause me even more problems) but I decided to give some of the other locators a go

Well I did notice my "LI" tags had id so I tried to get those but with Selenium you can't really play with the tags under a tag but I could try an '$sel->click($locator)' but that only works on 'clickable' thinks like links and not all the 'LI' on my page where 'clickable'

I then tried to get '$sel->mouse_over($locator)' into the act but as a good number of the 'LI's where not visible I was forced to write our long lists of mouse_overs before I got to an 'LI' I could click on. Well at least I have the menu tester finished but not the point of the test.

Finally I gave the 'dom' locator a try and my hopes and dreams where answered as this uses the underlying JS DOM to get what I want.

Fortunately there is lots in the DOM document object to help me as we have a handy links array right on is so in way of a test I tried

 my $links =>$sel->get_text('dom=document.links');

and nothing as I can only get 1 from that call silly me.

I do remember my JS so I tried

 my $link =>$sel->get_text('dom=document.links[1]');

and still nothing so I was a little upset but I had one more how about

 my $link =>$sel->get_attribute("dom=document.links[0]\@href"));

and I got my href value!! So I was back in the game and a few moments later I had

my $count= $sel->get_xpath_count('//a');

foreach my $index (0..$count-1){
    my $href = $sel->get_attribute("dom=document.links[$index]\@href"));

Of course here I remembered that the JS array was '0' based and changed the loop to fix that and so I ended the day on a happy note!


Leave a comment

About byterock

user-pic Long time Perl guy, a few CPAN mods allot of work on DBD::Oracle and a few YAPC presentations