Andrew Cooke | Contents | Latest | RSS | Previous | Next

C[omp]ute

Welcome to my blog, which was once a mailing list of the same name and is still generated by mail. Please reply via the "comment" links.

Always interested in offers/projects/new ideas. Eclectic experience in fields like: numerical computing; Python web; Java enterprise; functional languages; GPGPU; SQL databases; etc. Based in Santiago, Chile; telecommute worldwide. CV; email.

Personal Projects

Choochoo Training Diary

Last 100 entries

Surprise Paradox; [Books] Good Author List; [Computing] Efficient queries with grouping in Postgres; [Computing] Automatic Wake (Linux); [Computing] AWS CDK Aspects in Go; [Bike] Adidas Gravel Shoes; [Computing, Horror] Biological Chips; [Books] Weird Lit Recs; [Covid] Extended SIR Models; [Art] York-based Printmaker; [Physics] Quantum Transitions are not Instantaneous; [Computing] AI and Drum Machines; [Computing] Probabilities, Stopping Times, Martingales; bpftrace Intro Article; [Computing] Starlab Systems - Linux Laptops; [Computing] Extended Berkeley Packet Filter; [Green] Mainspring Linear Generator; Better Approach; Rummikub Solver; Chilean Poetry; Felicitations - Empowerment Grant; [Bike] Fixing Spyre Brakes (That Need Constant Adjustment); [Computing, Music] Raspberry Pi Media (Audio) Streamer; [Computing] Amazing Hack To Embed DSL In Python; [Bike] Ruta Del Condor (El Alfalfal); [Bike] Estimating Power On Climbs; [Computing] Applying Azure B2C Authentication To Function Apps; [Bike] Gearing On The Back Of An Envelope; [Computing] Okular and Postscript in OpenSuse; There's a fix!; [Computing] Fail2Ban on OpenSuse Leap 15.3 (NFTables); [Cycling, Computing] Power Calculation and Brakes; [Hardware, Computing] Amazing Pockit Computer; Bullying; How I Am - 3 Years Post Accident, 8+ Years With MS; [USA Politics] In America's Uncivil War Republicans Are The Aggressors; [Programming] Selenium and Python; Better Walking Data; [Bike] How Fast Before Walking More Efficient Than Cycling?; [COVID] Coronavirus And Cycling; [Programming] Docker on OpenSuse; Cadence v Speed; [Bike] Gearing For Real Cyclists; [Programming] React plotting - visx; [Programming] React Leaflet; AliExpress Independent Sellers; Applebaum - Twilight of Democracy; [Politics] Back + US Elections; [Programming,Exercise] Simple Timer Script; [News] 2019: The year revolt went global; [Politics] The world's most-surveilled cities; [Bike] Hope Freehub; [Restaurant] Mama Chau's (Chinese, Providencia); [Politics] Brexit Podcast; [Diary] Pneumonia; [Politics] Britain's Reichstag Fire moment; install cairo; [Programming] GCC Sanitizer Flags; [GPU, Programming] Per-Thread Program Counters; My Bike Accident - Looking Back One Year; [Python] Geographic heights are incredibly easy!; [Cooking] Cookie Recipe; Efficient, Simple, Directed Maximisation of Noisy Function; And for argparse; Bash Completion in Python; [Computing] Configuring Github Jekyll Locally; [Maths, Link] The Napkin Project; You can Masquerade in Firewalld; [Bike] Servicing Budget (Spring) Forks; [Crypto] CIA Internet Comms Failure; [Python] Cute Rate Limiting API; [Causality] Judea Pearl Lecture; [Security, Computing] Chinese Hardware Hack Of Supermicro Boards; SQLAlchemy Joined Table Inheritance and Delete Cascade; [Translation] The Club; [Computing] Super Potato Bruh; [Computing] Extending Jupyter; Further HRM Details; [Computing, Bike] Activities in ch2; [Books, Link] Modern Japanese Lit; What ended up there; [Link, Book] Logic Book; Update - Garmin Express / Connect; Garmin Forerunner 35 v 230; [Link, Politics, Internet] Government Trolls; [Link, Politics] Why identity politics benefits the right more than the left; SSH Forwarding; A Specification For Repeating Events; A Fight for the Soul of Science; [Science, Book, Link] Lost In Math; OpenSuse Leap 15 Network Fixes; Update; [Book] Galileo's Middle Finger; [Bike] Chinese Carbon Rims; [Bike] Servicing Shimano XT Front Hub HB-M8010; [Bike] Aliexpress Cycling Tops; [Computing] Change to ssh handling of multiple identities?; [Bike] Endura Hummvee Lite II; [Computing] Marble Based Logic; [Link, Politics] Sanity Check For Nuclear Launch; [Link, Science] Entropy and Life

© 2006-2017 Andrew Cooke (site) / post authors (content).

Selenium Web Testing

From: andrew cooke <andrew@...>

Date: Sat, 7 Aug 2010 19:31:39 -0400

I've been looking at Selenium, which is a system for testing web sites.  It's
very easy to use, for simple sites, and works impressively well.  Using a
Firefox plugin you "record" browsing a site and can then repeat that in
"playback mode" as a test.  You can also export the test as Python or Java
unit tests and run those against all the popular browsers on all the popular
operating systems.

That's pretty neat - you could have a bunch of VMs running different operating
systems and browsers, all running against a test web site.  I tested it by
running a Python unit test from Linux that tested Internet Explorer in a
Windows 7 VM.

However, for the particular case I had in mind there are some problems.  In
particular, it's not clear how to handle mixed namespaces (eg SVG is not in
the HTML namespace in the DOM) and, given how the system is implemented (as
Javascript accessing the DOM within the browser being tested) it will not work
with Adobe's SVG plugin on Windows.


Notes
-----

The "Selenium IDE" is a Firefox plugin that:
 * Lets you define tests  (and group them in suites)
 * Lets you *run* tests (against Firefox)
 * Lets you save test for future use, or to reun from other languages

So for simple, Firefox only tests, this is a very quick, simple solution.  For
more complex testing it is also a good way of generating tests.

Tests can follow links and do things like verify text (when defining a test,
highlight the text, right click and select the correct option).

A test when saved in the "internal" format is a HTML table of commands.  When
saved as Python file it looks like:

  from selenium import selenium
  import unittest, time, re

  class test(unittest.TestCase):

      def setUp(self):
          self.verificationErrors = []
          self.selenium = selenium("localhost", 4444, "*firefox", 
                                   "http://www.acooke.org")
          self.selenium.start()

      def test_selenium(self):
          sel = self.selenium
          sel.open("/")
          sel.click("link=Lepl")
          sel.wait_for_page_to_load("30000")
          sel.click("link=Support")
          sel.wait_for_page_to_load("30000")
          sel.click("link=Show Source")
          sel.wait_for_page_to_load("30000")
          try: self.failUnless(sel.is_text_present("Google Code"))
          except AssertionError, e: self.verificationErrors.append(str(e))

      def tearDown(self):
          self.selenium.stop()
          self.assertEqual([], self.verificationErrors)

  if __name__ == "__main__":
      unittest.main()


To run that, however, and to test other browsers, you need to install "Selnium
RC".  This is a bundle of packages that includes the server along with support
for various languages.

The server is a Java program that you run as:
  java -jar selenium-server.jar

Then, when you run the Python test...
  python test.py
..the server automatically opens firefox and runs the tests.  It's just like
someone is using your machine!

The only extra detail needed in practice is that "firefox" must be the binary,
not the usual script at /usr/bin/firefox (on Linux).  Otherwise you will see
the error

  Caution: '/usr/bin/firefox': file is a script file, not a real
  executable.  The browser environment is no longer fully under RC control

Since selenium checks for "firefox-bin" before "firefox" the easiest solution
is to:

1 - link firefox-bin to firefox in /usr/lib64/firefox
2 - include /use/lib64/firefox on the path

Then run the server as:

  PATH=$PATH:/usr/lib64/firefox java -jar selenium-server.jar

Note that you need firefox-bin to be in the same directory as firefox or you
will see the error:

  Could not read application.ini

With that fix, the server starts and kils firefox, and tests run repeatedly
(without it, only the first test worked - rerunning it somehoe treated the
website as a binary file).


So, next question - can we do the same on Windows?  I started a VB VM with
Windows 7, containing Java 6 and IE 8.  Downloading Selenium RC (the server)
and starting it, then running the same test (on Linux) but changed to call the
windows server, I got the error:

  Couldn't open app window; is the pop-up blocker enabled?"

Which is described at
http://stackoverflow.com/questions/1517623/internet-explorer-8-64bit-and-selenium-not-working

The simplest solution is to change the browser type to iexploreproxy.  The
following code, run on Linux, invokes IE on Windows and gives a successful
test:

  from selenium import selenium
  import unittest, time, re

  class test(unittest.TestCase):

      def setUp(self):
          self.verificationErrors = []
          self.selenium = selenium("10.1.0.28", 4444, "*iexploreproxy", 
                                   "http://www.acooke.org")
          self.selenium.start()

      def test_selenium(self):
          sel = self.selenium
          .... as before

Where 10.1.0.28 is the VM address.


This can be automated further with Selnium Grid, which automatically runs
tests on different machines.


OK, so now to test a web page with SVG.

Hmmm.  Suddenly (well, hours later....) this is not so great.  First, the site
opens new windows on clicks.  These have a "_blank" target.  Selenium has a
command to identify windows by title, but it doesn't work in the IDE (the
Firefox plugin).  After much frustration I found that it *does* work when used
via the server.

Also, because the link is loaded into a new window (ie not the one that
Selenium is watching) the test does not wait for completion.  So a fixed
period wait (30s) needs to be added.

And when I click on a link in the SVG, the selenium IDE records nothing.  I
can add this explicitly to a Python test, but I can't work out what to add.

I have experimented with specifying a namespace in an xpath expresison and
also by using javascript.  Javascript can be tested in the browser address box
(running selenium each time is slow because of waiting for pages) and
unfortunately the code below (and related attempts) does not work.

javascript:alert(function(){var a = document.getElementsByTagName('a');var result = [];for (var i=0; i<a.length; i++) {if (a[i].href == 'some-url-here'){return a[i];}}return null;}())

javascript:alert(function(){var a = document.getElementsByTagNameNS('http://www.w3.org/2000/svg', 'svg'); return a[0];}())

(Javascript can be specified inside selenium to identify the target - see the
"dom=" protocol in the documentation for the Python library).

Worse, on IE I suspect this would also be broken by the plugin.

So I stalled at this point.  Selenium works surprisingly well (better than I
expected), but does not handle SVG well - there appear to be problems with
namespaces and, likely IE's plugin.

Andrew

Comment on this post