Website testing using custom subclass of BrowserTest
On this page we test whether the birth date of Van Morrisson is listed correctly on AllMusic.
We start by navigating to the artist's overview page on AllMusic and then perform the same check in different ways:
- First with plain BrowserTest,
- then with a custom subclass, nl.hsac.fitnesse.sample.AllMusicTest, and
- finally with a Slim scenario[?].
Doing this in Java 'hides' the exact way the birth date is determined from the test (and its result). While a scenario would have made this part of the 'test domain'.
Hiding details can either be a good (e.g. more focus on what is relevant to test, smaller test report), or bad (e.g. 'what was done exactly in this method?') thing.
Which approach is more suitable depends on your tests' context (and the complexity of what is to be done)...
There are some things a Java method can do that a scenario cannot: for instance using conditional logic (if statements), or looping (for or while statements), or even customize the heuristic used to find places.
Navigate to right page
Navigating to the right page is done only once (all subsequent test approaches use the same browser window, which will be at the correct location already).script | browser test | |||
set continue if ready state interactive | true | |||
open | https://www.allmusic.com | |||
show | click if available | I accept | false | |
enter Timed-out waiting (after 10s). Page content:(Screenshot not available) |
Van Morrison | as | Search | |
press org.openqa.selenium.TimeoutException: timeout: Timed out receiving message from renderer: -0.001 (Session info: chrome=80.0.3987.87) (Driver info: chromedriver=80.0.3987.16 (320f6526c1632ad4f205ebce69b99a062ed78647-refs/branch-heads/3987@{#185}),platform=Windows NT 10.0.10586 x86_64) (WARNING: The server did not provide any stacktrace information) Command duration or timeout: 0 milliseconds Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03' System info: host: 'localhost', ip: '127.0.0.1', os.name: 'Linux', os.arch: 'amd64', os.version: '4.15.0-1055-gcp', java.version: '1.8.0_242' Driver info: org.openqa.selenium.remote.RemoteWebDriver Capabilities {acceptInsecureCerts: false, acceptSslCerts: false, applicationCacheEnabled: false, browserConnectionEnabled: false, browserName: chrome, chrome: {chromedriverVersion: 80.0.3987.16 (320f6526c1632..., userDataDir: C:\Users\ADMINI~1\AppData\L...}, cssSelectorsEnabled: true, databaseEnabled: false, goog:chromeOptions: {debuggerAddress: localhost:49760}, handlesAlerts: true, hasMetadata: true, hasTouchScreen: false, javascriptEnabled: true, locationContextEnabled: true, mobileEmulationEnabled: false, nativeEvents: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: WINDOWS, platformName: WINDOWS, proxy: Proxy(), rotatable: false, setWindowRect: true, strictFileInteractability: false, takesHeapSnapshot: true, takesScreenshot: true, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unexpectedAlertBehaviour: ignore, unhandledPromptBehavior: ignore, version: 80.0.3987.87, webStorageEnabled: true, webdriver.remote.sessionid: 74ed0e4e6eb242638abd370a507...} Session ID: 74ed0e4e6eb242638abd370a507c4669 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:214) at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:166) at org.openqa.selenium.remote.http.JsonHttpResponseCodec.reconstructValue(JsonHttpResponseCodec.java:40) at org.openqa.selenium.remote.http.AbstractHttpResponseCodec.decode(AbstractHttpResponseCodec.java:80) at org.openqa.selenium.remote.http.AbstractHttpResponseCodec.decode(AbstractHttpResponseCodec.java:44) at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:609) at org.openqa.selenium.remote.RemoteWebDriver$RemoteTargetLocator.activeElement(RemoteWebDriver.java:927) at nl.hsac.fitnesse.fixture.util.selenium.SeleniumHelper.getActiveElement(SeleniumHelper.java:659) at nl.hsac.fitnesse.fixture.slim.web.BrowserTest.sendKeysToActiveElement(BrowserTest.java:664) at nl.hsac.fitnesse.fixture.slim.web.BrowserTest.press(BrowserTest.java:641) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at fitnesse.slim.fixtureInteraction.SimpleInteraction.methodInvoke(SimpleInteraction.java:322) at nl.hsac.fitnesse.fixture.slim.SlimFixture.invoke(SlimFixture.java:61) at nl.hsac.fitnesse.fixture.slim.web.BrowserTest.superInvoke(BrowserTest.java:145) at nl.hsac.fitnesse.fixture.slim.web.BrowserTest.invoke(BrowserTest.java:92) at nl.hsac.fitnesse.fixture.slim.SlimFixture.aroundSlimInvoke(SlimFixture.java:41) at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at fitnesse.slim.fixtureInteraction.SimpleInteraction.methodInvoke(SimpleInteraction.java:322) at fitnesse.slim.fixtureInteraction.SimpleInteraction.callMethod(SimpleInteraction.java:305) at fitnesse.slim.fixtureInteraction.SimpleInteraction.invokeMethod(SimpleInteraction.java:290) at fitnesse.slim.fixtureInteraction.SimpleInteraction.findAndInvoke(SimpleInteraction.java:217) at fitnesse.slim.MethodExecutor.findAndInvoke(MethodExecutor.java:18) at fitnesse.slim.FixtureMethodExecutor.execute(FixtureMethodExecutor.java:18) at fitnesse.slim.StatementExecutor.getMethodExecutionResult(StatementExecutor.java:139) at fitnesse.slim.StatementExecutor.call(StatementExecutor.java:112) at fitnesse.slim.instructions.CallAndOptionalAssignInstruction.executeInternal(CallAndOptionalAssignInstruction.java:30) at fitnesse.slim.instructions.Instruction.execute(Instruction.java:29) at fitnesse.slim.ListExecutor$Executive.executeStatement(ListExecutor.java:49) at fitnesse.slim.ListExecutor$Executive.executeStatements(ListExecutor.java:43) at fitnesse.slim.ListExecutor.execute(ListExecutor.java:85) at fitnesse.slim.SlimServer.executeInstructions(SlimServer.java:82) at fitnesse.slim.SlimServer.processOneSetOfInstructions(SlimServer.java:75) at fitnesse.slim.SlimServer.tryProcessInstructions(SlimServer.java:62) at fitnesse.slim.SlimServer.serve(SlimServer.java:47) at fitnesse.testsystems.slim.InProcessSlimClient$1.run(InProcessSlimClient.java:55) at java.lang.Thread.run(Thread.java:748) . Page content:(Screenshot not available) |
enter | |||
click Timed-out waiting (after 10s). Page content:(Screenshot not available) |
Van Morrison | |||
wait for visible Timed-out waiting (after 10s). Page content:(Screenshot not available) |
Album Highlights |
Using BrowserTest
script | browser test Test not run | ||
check | value of | xpath=//div[h4[contains(text(),'Born')]]/div | August 31, 1945 in Belfast, Northern Ireland Test not run |
Using a custom subclass, makes the check look like...
Using AllMusicTest
We need to indicate in which package our custom class can be found.
import |
nl.hsac.fitnesse.sample Test not run |
script | all music test Test not run | ||
note | Use custom method to birth date | ||
check | birth data | August 31, 1945 in Belfast, Northern Ireland Test not run | |
note | Using a customized heuristic, we can also retrieve similar fields | ||
check | value of | Born | August 31, 1945 in Belfast, Northern Ireland Test not run |
check | value of | Also Known As | George Ivan Morrison Test not run |
And using a scenario
Using a Scenario
The scenario 'hides' the xpath from the test script, but its definition can be found (and updated) in the wiki. And the test report/result will show what was done (unlike for the custom fixture).
No Java knowledge or development environment is needed to create and maintain a scenario, which may also be an advantage.
scenario | check basic info value _ is _ | key, expected | |
check | value of | xpath=//div[h4[contains(text(),'@{key}')]]/div | @{expected} |
script | browser test Test not run | ||||||||||
check basic info value | Born | is | August 31, 1945 in Belfast, Northern Ireland | ||||||||
| |||||||||||
check basic info value | Also Known As | is | George Ivan Morrison | ||||||||
|