Skip to content

Instantly share code, notes, and snippets.

@jaredhirsch
Created October 3, 2012 15:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaredhirsch/0874785e0479451fa801 to your computer and use it in GitHub Desktop.
Save jaredhirsch/0874785e0479451fa801 to your computer and use it in GitHub Desktop.
testing talk

Fun with browsers: a test-writing workshop

jquery-style hacking webdriver with nodejs.

Overview:

  1. background info
  2. examples
  3. talk about waiting
  4. code organization, briefly (what to hack on today)
  5. your turn!

1. background info

webdriver: tool for automating browsers

  • part of the selenium project
  • the newer API; selenium RC is the older API
  • "local" process (test code and standalone-server)
  • "remote" process (browser)
    • local and remote may be running on the same machine
  • RESTful JSON protocol
    • supports finding elements, clicking, typing, switching windows, etc
  • JS bindings: admc/wd is a github project that provides node-style javascript bindings
    • see admc/wd README for API docs

2. example code

Suppose you want to click login, enter email & password, click submit, then check you logged in.

admc/wd provides a node-style callback-passing API by default:

// b is for browser.
b.get(someUrl, function(err) {
  b.elementByCss('.login', function(err, el) {
    b.clickElement(el, function(err) {
      b.elementByCss('#email', function(err, el) {
        b.type(el, 'foo@bar.com', function(err) { 
          b.elementByCss('#password', function(err, el) {
            b.type(el, 's3cret', function(err) {
              b.elementByCss('button.submit', function(err, el) {
                b.click(el, function(err) {
                  b.elementByCss('.logged-in', function(err, el) {
                    b.text(el, function(err, text) {
                      assert.equal(text, 'foo@bar.com');
                    });
                  });
                });
              });
            });
          });
        });
      });
    });
  });
});

admc/wd also provides a chainable syntax:

b.chain()
  .get(someUrl)
  .elementByCss('.login', function(err, el) {
    b.clickElement(el, errCheck);
   })
  .elementByCss('#email', function(err, el) {
    b.type(el, 'foo@bar.com', errCheck);
   })
  .elementByCss('#password', function(err, el) {
    b.type(el, 's3cret', errCheck);
   })
  .elementByCss('button.submit', function(err, el) {
    b.click(el errCheck);
   })
  .elementByCss('.logged-in', function(err, el) {
    b.text(el, function(err, text) {
      assert.equal(text, 'foo@bar.com');
    });
  });

we've added a super-sugary wrapper API which makes this moar fun:

b.chain()
  .get(someUrl)
  .wclick('.login')
  .wtype('#email', 'foo@bar.com')
  .wtype('#password', 's3cret')
  .wclick('button.submit')
  .wtext('.logged-in', function(err, text) { 
    assert.equal(text, 'foo@bar.com');
  });

3. waiting is hard.

  • selenium goes at full speed by default
    • way faster than any human could click
  • implicit wait: in the DOM yet?
    • provided for us
  • explicit wait: in the DOM and visible/active yet?
    • we have to do the polling
    • wfind(), wclick(), wtype(), wtext(), wwin()

4. writing tests: code organization

  • grab the 'kapow' branch of mozilla/browserid
  • tests live inside the automation_tests directory for now
  • we are using vows, behind a wrapper that reduces vows' verbosity. (lib/vowsHarness.js)
    • see lloyd/meh/blob/master/new_user_secondary_test.js for vows unwrapped
  • we have the selectors and page functions in the pages directory
  • we have the list of URLs in one file (lib/persona_urls.js)
  • we extract duplication per page/site, a very lightweight version of POM concept (lib/dialog.js)
    • a little abstraction goes a long way. let's keep it light (for now) and seek structure as pain arises, not before.

a side note:

speaking of challenging each other! huge props to lloyd for pointing out the JS alternative, prototyping it (see lloyd/meh on github), and providing tons of feedback and support.

5. your turn!

Grab the kapow branch of mozilla/browserid. Go into automation-tests. npm install. hack.

Refs for getting started: see automation-tests README

  • admc/wd is our webdriver binding
  • our API extensions are documented in the README
  • jsonwireprotocol is what it all comes down to
  • there are tests inside the kapow branch automation_tests folder
  • there is earlier scratch work inside lloyd/meh and 6a68/meh

When you've had fun playing around, if you want to really write some tests:

  • the automation-test crew has a prioritized list of tests, see the automation-tests README
  • if you want to hack on something, sign up for it in the etherpad
    • team up on stuff!

If you get stuck and have questions, ping me or lloyd! I'll be around on IRC/Vidyo

questions?

@jaredhirsch
Copy link
Author

this is a little out of date. the tests have been merged into the main dev branch, and the kapow branch is gone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment