Pliant AllianceSoftware development notes & tools

Building reliable browser tests with Selenium

By 2005, web applications were doing more than serving pages, and development teams needed a repeatable way to check the workflows customers relied on. Selenium filled that gap by controlling a real browser: it could open a page, enter data, click controls and examine the result. A script could therefore replay an important journey and report whether the application behaved as expected, rather than leaving every check to a tester opening browser windows by hand.

Selenium did not understand a site’s rules or write the ideal test suite. It gave testers a practical way to automate the browser while keeping the workflow visible. The strongest suites treated commands as evidence, not decoration: each action led towards an assertion, data was controlled, and waiting was tied to a visible condition. That discipline mattered in Australia, where teams were already balancing enterprise Windows systems, newer Linux desktops and uneven connections.

Choose the right Selenium component

In 2006, Selenium covered three related components, and choosing the wrong one could waste a lot of time. Selenium IDE was a Firefox extension for recording and editing browser actions. Selenium Core ran an HTML test suite directly within a browser. Selenium Remote Control used a server and proxy to start and control browsers while allowing tests to be written in languages such as Java, Python, Ruby or Perl.

IDE was useful for exploring a site and producing a first draft. Its recorded commands were rarely dependable as final code, however, because a recording captured timing and layout rather than intent. Core suited self-contained pages and quick experiments. RC was the better foundation for a repeatable team suite, especially when a test needed several pages, explicit waits or results that could be collected by a build tool.

A workable approach was to use the IDE while learning the application, then rewrite the valuable paths in RC with plain names and assertions. Keep the choice consistent within a suite. Mixing recorded fragments with hand-written tests created two dialects for the same job, making failures harder to explain and ownership less clear.

Model workflows before recording clicks

Begin with a small set of journeys rather than every click. For an Australian online shop, that might mean finding a product, adding it to a basket, changing a delivery address, applying a discount and reaching the payment screen. A service portal might instead cover signing in, updating a contact address and downloading a statement. These flows reveal broken integrations and navigation errors without producing hundreds of overlapping checks.

Local details belong in those journeys. An Australian storefront may use a .com.au domain, prices including 10% GST, day-first dates such as 04/03/06, and four-digit postcodes. Support copy may refer to an “organisation” or a “service centre”. Testing Australian English and local formatting catches defects that a generic overseas fixture misses, especially when dates are parsed, totals are calculated or addresses are validated.

Each scenario should have a clear starting state, a defined action sequence and an observable ending. Put setup data in a fixture or named helper, and assert the important result rather than every temporary screen. If a discount code expires, replace it with a controlled value. A test that depends on yesterday’s stock, a live customer record or the current clock will eventually report a defect that belongs to the fixture, not the application.

Keep locators stable and readable

Locators are the bridge between the test and the page. Prefer a stable id or name that belongs to the application, then use visible labels and text when the markup offers nothing better. Avoid long XPath expressions tied to generated table structure, because inserting one row can alter their position. A CSS selector can be concise, but it still needs to be checked in every supported browser rather than assumed to behave identically.

Readable selectors also make failed runs easier to diagnose. A name such as customerPostcode says more than div[3]/span[2], and it lets a developer see which contract the test expects the page to provide. When several controls share a title, narrow the search using a nearby stable attribute instead of relying on screen position.

Centralise repeated navigation in small helper methods. A loginAsCustomer function, for example, should enter known credentials and wait for the account page, while each test continues with its own purpose. This keeps scripts compact without hiding the assertions that matter. It also limits repair work: when a button label changes, one helper can be updated instead of every recorded sequence.

Wait for the application, not the clock

Fixed sleeps are a common weakness in early browser automation. pause(5000) assumes the slowest page will always respond within five seconds; on a busy machine it is merely slow, while on a quick one it wastes time. More seriously, the same delay can be too short tomorrow. A wait tied to the expected condition is faster in the normal case and more reliable under load.

Selenium IDE provided waits for an element or expected text to appear, while RC offered explicit waits around conditions and a timeout. Use them after actions that trigger a request, redirect or validation message. Wait for the presence of the successful result, not for an intermediate spinner to disappear, because the useful element may not yet exist at the moment the spinner does.

Timeouts should be long enough for a genuinely slow operation but short enough to expose a stuck browser within the working day. Record the timeout in one setting, or keep it consistent across a suite, and report which condition timed out. During 2006, with Australian metropolitan teams often testing over ADSL and some regional offices on slower links, generous browser startup time could also prevent a healthy suite from failing before it began.

Test the browsers Australian teams actually used

The browser mix mattered more than a fashionable wish list. Internet Explorer 6 remained common in Australian offices because enterprise intranets and administrative systems depended on it. Firefox 1.5 was increasingly attractive to technical teams and developers, while a smaller number of businesses used Safari on Mac or Linux desktops. A suite that passed only in Firefox could miss the rendering and JavaScript problems seen by a large share of staff.

Build a small matrix from supported usage rather than testing every permutation. Run a core journey—sign in, submit a form, confirm a record—in each important browser, then run deeper workflows in the primary desktop environment. Keep browser versions, proxy settings and zoom levels recorded beside the results. A difference between one workstation and another is otherwise easy to mislabel as an application defect.

The local network deserves the same attention. A developer in Perth or Darwin might work through a different connection from a colleague in Sydney or Melbourne, but the suite should still target a controlled test server with predictable responses. Where possible, keep the application server, database and test browser on the same network segment, then exercise connection failures deliberately rather than relying on an office outage to reveal them.

Keep test data and side effects under control

Run destructive or data-changing checks outside production. A Selenium test can complete a real order, change a password or send an email as easily as a person can, so environment controls are part of the test design. Use a dedicated staging database, synthetic customer records and test payment services. The endpoint under test must be obvious in the configuration, because a mistyped URL can turn a routine run into a customer-facing incident.

Synthetic data also supports Australian privacy obligations. Private-sector organisations were subject to the Privacy Act 1988, with later reforms strengthening how personal information was handled, and many internal processes reflected the Spam Act 2003. Test records should contain invented names, addresses and identifiers, not copied customer files. Keep credentials in the test environment, restrict access to result files, and remove them when the retention period ends.

Stub outbound effects where practical. Route confirmation emails to a mail catcher, use a sandbox payment provider, and reset stock or account flags after a scenario. If the application must call a genuine service, give it a dedicated test account with strict limits. Cleanup belongs in the test harness, including after failure, so one broken run does not contaminate the next and make every later result suspect.

Make the suite part of everyday delivery

A suite becomes valuable when it runs without a person sitting beside it. Selenium RC could start its control server, launch a browser, execute language-specific test classes and return a pass or failure report. Wire that sequence into a nightly build and a pre-release check, then publish the report where the whole team can see it. Repetition catches timing faults and environment differences that a single reassuring manual pass will miss.

Schedule matters for distributed Australian teams. Melbourne and Sydney normally share Eastern Time, Brisbane shifts by an hour during daylight saving, and Perth remains two hours behind Sydney. A late run in Sydney can leave overnight results ready for morning in Perth and Melbourne, while the machine and database remain under controlled ownership. The report should carry dates in an unambiguous format, because 04/03/06 means 4 March in Australia and 3 April in the United States.

Keep failures actionable. Give every scenario a specific name, retain the browser state, capture the current URL and relevant page text, and save the underlying error rather than only a red status. Assign ownership by the component that changed and keep the suite in source control with the application. A well-built Selenium suite was more than a collection of browser commands: it was an Australian team’s durable, repeatable evidence that critical online workflows still worked.