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
$var=['',
'',
'',
...
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
$sel->get_xpath_count('//li/a');
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
li[1]/a
..
li[9]/a
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