Locating Web Elements with Gwen

Gwen supports locating elements on web pages using all the standard Selenium selectors and additionally by JavaScript too. In this post, we are going to explore them. To make it a little more fun we will use the Gwen REPL which will enable us to verify our locator expressions interactively against a running web application in a browser as we go.

The first thing you’ll need to do is install Gwen somewhere on your machine. It’s simple to do. Just download this gwen-workspace.zip and unpack it somewhere on your drive and open a command prompt into the unpacked location. If you run into any trouble or would prefer to follow our install guide, you can start here and then come back.

Once you’re ready, type the following command at the terminal in the root gwen-workspace directory where you installed Gwen:

Linux/Mac/PowerShell:

./gwen

Windows DOS:

gwen

The first time you launch Gwen it will take just a little time to download the latest version of itself. Subsequent launches won’t have to do that and will start faster.

The REPL will start with a gwen> prompt open:

   __ ___      _____ _ __     _
  / _` \ \ /\ / / _ \ '_ \   { \,"
 | (_| |\ V  V /  __/ | | | {_`/
  \__, | \_/\_/ \___|_| |_|   `
  |___/

Welcome to gwen-web v2.35.1

INFO - Environment context initialised
INFO - gwen-web.sh -r target/reports -p gwen.properties,browsers/chrome.properties,env/local.properties

REPL Console

Enter steps to evaluate or type exit to quit..

gwen> 

In the examples that follow we are borrowing the Selenium Test Page from automationtesting.com to demonstrate locating web elements using all of the available mechanisms in Gwen.

Keep in mind that Gwen is case sensitive. So you will need to use the same casing that is shown in all the examples here.

Enter the following step into the REPL to have Gwen open up a new browser session with the Selenium Test Page all ready and loaded (you can copy and paste the step if you like):

When I navigate to "https://automationintesting.com/selenium/testpage/"

Locating elements with Selenium selectors

We’ll start with ID locators which simply locate elements by their HTML id attribute. The Selenium Test page that we have open in the browser has a First name field in it. If we right click and inspect that field in the browser we will see that it is defined in HTML as follows:

<input id="firstname" type="text" placeholder="Enter your first name">

Enter the following step into Gwen REPL prompt to define a locator named firstNameById for finding this field:

Then firstNameById can be located by id "firstname"

This will instruct Gwen to bind the name firstNameById to the By.id("firstname") Selenium locator under the hood. We can test that it works by entering the following at the REPL prompt:

When I locate firstNameById

Gwen will find and highlight the field in yellow inside the browser session that we opened. If you missed it, rearrange your REPL and browser windows a bit so you can see both side by side and repeat the last command (you can use the up arrow in the REPL to recall the last command).

Demo of locating a web element with Gwen on FriendlyTester‘s Selenium Test Page

Now that we have proven that our firstNameById locator binding works, we can perform an operation on the field by referencing it by name in any one of the predefined Web DSL steps that Gwen supports for web automation. For example, we can type a name into the form by entering the following step into the REPL:

And I type "Gwen" in firstNameById

Gwen will locate and enter the name in the field.

Similarly, we can also locate the form in the page which is defined in the page HTML as:

<form id="contactus" name="contactform">

Let’s locate by name this time. Enter the following step into Gwen REPL prompt to define a locator named formByName for finding this form:

Given formByName can be located by name "contactform"

This will instruct Gwen to bind the name formByName to the By.name("contactform") Selenium locator . We can test it by entering the following at the REPL prompt:

When I locate formByName

Gwen will find and highlight the form in inside the browser. We can then submit the form by entering the following step into the REPL:

And I submit formByName

Gwen will locate and submit the form. Let’s exit the REPL and see how we can use the locators we just defined to execute a Gherkin feature file. Type exit at the gwen> prompt to return to your OS.

exit

Create a subfolder named se-test inside the features subfolder of your Gwen workspace. Then create and save a new text file named SeleniumTestPage.feature in that subfolder with the following content:

 Feature: Selenium Test Page

Scenario: Submit the test form
    Given I am on the Selenium test page
     When I provide some contact details
      And I submit the test form
     Then nothing should happen

Create and save another text file named SeleniumTestPage.meta in the same subfolder with the following content:

 Feature: Selenium Test Page Meta

@StepDef
Scenario: I am on the Selenium test page
     When I navigate to "https://automationintesting.com/selenium/testpage/"
     Then firstNameById can be located by id "firstname"
      And formByName can be located by name "contactform"

@StepDef
Scenario: I provide some contact details
     When I type "Gwen" in firstNameById

@StepDef
Scenario: I submit the test form
     When I submit formByName

@StepDef
Scenario: nothing should happen
     Then the current URL should end with "?"

Type the following command at your OS terminal prompt to have Gwen load the meta file and bind it to the feature file to automate execution:

Linux/Mac/PowerShell:

./gwen features/se-test

Windows DOS:

gwen features/se-test

Gwen will execute the feature by performing all the same actions we performed earlier in the REPL and will leave the REPL session open when done. The locators we defined are now bound in Gwen’s memory and we can continue experimenting with them in the REPL if we wish. Enter the following command to have Gwen submit the form again:

When I submit formByName

Enter the 3rd step in our feature directly into the REPL:

And I submit the test form

Gwen will match it to the 3rd @StepDef annotated Scenario in the meta file by name (this is how step definitions work in Gwen) and execute all the steps that we defined there. Type exit at the Gwen REPL prompt when you are ready to return to your OS.

We just demonstrated how you can locate an element by id with Gwen. You can use the same approach to locate elements using any one of the other standard Selenium locator mechanisms. Borrowing some locator examples from Friendly Tester’s Free Selenium Course, here is how you would define the equivalents in Gwen:

Given genderByClass can be located by class name "gender"

  And firstNameByXPath can be located by xpath "//*[@id="firstname"]"

  And linkByTag can be located by tag name "a"

  And linkByCSS can be located by css selector "div a"

  And linkByLinkText can be located by link text "Our Policy"

  And linkByPartialText can be located by partial link text "Policy"

If you load these locators into the Gwen REPL or define them in your meta file, you will then be a able to perform operations on those elements such as:

When I select "Female" in genderByClass

And I clear firstNameByXPath

And I click linkByTag

Locating elements with JavaScript

We said at the beginning that Gwen can also locate elements by JavaScript. Sometimes this can help us locate dynamically rendered elements more reliably.

If you wanted to, you could define the form locator using a vanilla JavaScript expression like this :

Given formByJS can be located by javascript "document.getElementsByName('contactform')[0]"

Or a form locator using a JQuery expression (if the jquery library is loaded in the browser page) like this:

And formByJQuery can be located by javascript "$('#contactus').get(0)"

Or in extreme cases where the standard locators do not suffice and you have to resort to executing a custom script on a page to find an element, you could do so with an anonymous JavaScript function in a DocString like this:

And elemByJSFunc can be located by javascript
      """
      (function() {
        var elem = ..
          // dynamic logic to find element 
          // based on some fancy rules,
          // conditions or what have you
        return elem;
      })();
      """

To test this last one in the REPL, you would have to use the paste mode since the step spans multiple lines.

That’s it! We hope this has been a good small introduction to locators in Gwen for you.

Advertisements

Visual Testing with Gwen and AppliTools

AppliTools have made visual UI testing extremely simple with their online service. Automating basic visual tests with their Eyes SDK involves just three essential activities:

  1. Starting a new visual test session
  2. Saving one or more checkpoint images
  3. Closing the session and checking the results

Some of our Gwen users that we support have recently enquired about visual testing and we decided to provide it by integrating with AppliTools in gwen-web version 2.32.0.

To perform visual testing with Gwen, you will need:

Set API key in your Environment

Once you have the above, you need to set the APPLITOOLS_API_KEY environment variable on your host (where Gwen will run) to your API key value.

Linux

export APPLITOOLS_API_KEY=your-api-key

Windows

set APPLITOOLS_API_KEY=your-api-key

Start a Visual Test Session

Consider the following executable Gwen feature (and associated meta available here):

Feature:

 Feature: Todo items

Scenario: Add items in my Todo list
    Given I launch the Todo app
     When I add a "Walk the dog" item
      And I add a "Get the milk" item
     Then the number of active items should be "2"

Scenario: Complete one item
     When I tick the "Get the milk" item
     Then the number of active items should be "1"

Scenario: Complete another item
     When I tick the "Walk the dog" item
     Then the number of active items should be "0"

Now let’s say we want to add some visual testing to this.

The first thing we will need to do is instruct Gwen to start a new visual test session and give it a name and viewport size. For example, the following Gwen step will create a new visual test session named “Todo items” and set the viewport size to 600 pixels high and wide:

  • I start visual test as "Todo items" in 600 x 600 viewport (see DSL here)

We can insert this at line 5 in the feature above as follows:

 Feature: Todo items

Scenario: Add items in my Todo list
    Given I launch the Todo app
      And I start visual test as "Todo items" in 600 x 600 viewport
     When ..

Checkpoint Screenshot Images

With the visual test session started, we can now start taking screenshots of the viewport and save them as checkpoints in AppliTools with a name and match level. For example, we can checkpoint the initial state of the Todo UI after the application has loaded and our visual test session has started. At this stage, the Todo UI will have no items in it and we can save the checkpoint of that image under the name “No Todo items” in AppliTools using the STRICT (layout and content) match level as follows:

  • I check viewport visual as "No Todo items" using STRICT match (see DSL here)

We can insert this at line 6 in the feature above as follows:

 Feature: Todo items

Scenario: Add items in my Todo list
    Given I launch the Todo app
      And I start visual test as "Todo items" in 600 x 600 viewport
      And I check viewport visual as "No Todo items" using STRICT match
     When ..

Similarly, we can checkpoint the screenshot after adding two items as follows (line 10 below):

 Feature: Todo items

Scenario: Add items in my Todo list
    Given I launch the Todo app
      And I start visual test as "Todo items" in 600 x 600 viewport
      And I check viewport visual as "No Todo items" using STRICT match
     When I add a "Walk the dog" item
      And I add a "Get the milk" item
     Then the number of active items should be "2"
      And I check viewport visual as "Active Todo items" using STRICT match
      ..

And checkpoint the screenshot after we complete (tick) each item as follows (lines 15 and 20 below):

 Feature: Todo items

Scenario: Add items in my Todo list
    Given I launch the Todo app
      And I start visual test as "Todo items" in 600 x 600 viewport
      And I check viewport visual as "No Todo items" using STRICT match
     When I add a "Walk the dog" item
      And I add a "Get the milk" item
     Then the number of active items should be "2"
      And I check viewport visual as "Active Todo items" using STRICT match

Scenario: Complete one item
     When I tick the "Get the milk" item
     Then the number of active items should be "1"
      And I check viewport visual as "One completed Todo item" using STRICT match

Scenario: Complete another item
     When I tick the "Walk the dog" item
     Then the number of active items should be "0"
      And I check viewport visual as "All completed Todo items" using STRICT match

This gives us a total of four checkpoint images for our visual test.

Close Session and Check Results

The final step is to close the session and check that the visual test has passed. In Gwen we can do this with the following DSL step:

  • the visual test should pass (see DSL here)

We can insert this line at the end of the feature as follows:

 Feature: Todo items

Scenario: Add items in my Todo list
    Given I launch the Todo app
      And I start visual test as "Todo items" in 600 x 600 viewport
      And I check viewport visual as "No Todo items" using STRICT match
     When I add a "Walk the dog" item
      And I add a "Get the milk" item
     Then the number of active items should be "2"
      And I check viewport visual as "Active Todo items" using STRICT match

Scenario: Complete one item
     When I tick the "Get the milk" item
     Then the number of active items should be "1"
      And I check viewport visual as "One completed Todo item" using STRICT match

Scenario: Complete another item
     When I tick the "Walk the dog" item
     Then the number of active items should be "0"
      And I check viewport visual as "All completed Todo items" using STRICT match
      And the visual test should pass

This last step will close the visual test session in AppliTools and return successfully if all checkpoint images pass their respective match level checks. This first time you run a visual test, AppliTools will baseline all checkpoint images and return a successful result. Subsequent runs will compare all respective images with that baseline using the comparison strategy defined by the match level specified at each checkpoint. Any failures will result in an error that Gwen will report.

AppliTools Dasbhoard

Whether all visual checks pass or not, Gwen will provide a link in the console and in the evaluation report to the online AppliTools dashboard containing the detailed results.

Console:

INFO - Evaluating Step: And the visual test should pass
INFO - Visual check status: Passed. Details at: https://applitools/dashboard-url
INFO - [406ms] Passed Step: And the visual test should pass

HTML Report:

Dashboard:

From the AppliTools dashboard, you can inspect and resolve any failures.

Launching the Example

The sample feature described in this post and associated meta are bundled in every Gwen distribution and are available on GitHub here also:

If you install Gwen, you can launch the example in your installation directory on the command line as follows (if you installed a Gwen workspace, you can omit the -r target/reports parameter, don’t forget to set the APPLITOOLS_API_KEY environment variable as described earlier):

Linux

./gwen -b -r target/reports features/visual/todo

Windows

gwen -b -r target/reports features/visual/todo

The Gwen evaluation report will be generated here (relative to your install directory): target/reports/index.html

The example here inlines the visual testing steps in the feature itself, but you could choose to externalise them to Gwen meta to keep your features clean in your own projects if you wish.

More Info

You can also override various AppliTools defaults and runtime aspects in Gwen. For this and more details, see Gwen visual testing on our wiki.

More to Come

Gwen currently supports very basic visual testing with AppliTools (as described above). AppliTools itself has much more features and capabilities which we have not yet fully explored or integrated. We will integrate more capabilities as time goes on and as users start providing us with feedback.

Thanks

We thank the team at AppliTools for helping and supporting us and hope our Gwen users will like this feature and find it very useful.

Gwen in Summary

Simpler web automation.

A Java runtime, a web browser, your favourite text editor, and the Gwen interpreter is all you need to start automating.

No clickety-click drag-drop mouse-pointy UI or dev-centric page-object code-compiling IDE or plugin required.

The interpreter is open source.

The automation is reusable, scalable, and shareable.

Many execution modes including sequential, parallel, dry run, and interactive REPL are provided.

Many reporting formats including JUnit XML, cucumber JSON, and pretty HTML are supported.

JavaScript can be injected in places if needed.

A CLI makes it easy to run locally and intergrate with any on-premise or on-cloud build server.

Git workspaces make it easy for teams to collaborate.

A package manager downloads and installs native browser drivers for you.

Built on Gherkin and Selenium.

Easy to run on BrowserStack, Sauce Labs, Aerokube Selenoid and other grids.

Matured in industry over 4 years.

Active user community is growing.

Gwen home page: http://gweninterpreter.org

Share with your friends.

Feedback welcomed.

Running Gwen on BrowserStack

BrowserStack allows you to run automated Selenium tests on a variety of platforms, browsers, and devices on the cloud. Since Gwen is built on Selenium and also supports remote web driver, you can easily run your Gwen tests “as is” on BrowserStack too. As of gwen-web version 2.25.1, all you need to do is provide some runtime properties.

Remote URL

If you sign up for a BrowserStack account, you will receive a user name and access key. Add the following settings to your gwen.properties file to configure your connection to BrowserStack:

file: ~/gwen.properties

bs.user = your-browserstack-username
bs.key = your-browsetstack-access-key
gwen.web.remote.url = https://${bs.user}:${bs.key}@hub-cloud.browserstack.com/wd/hub

Target Capabilities

BrowserStack provides a neat capabilities page that can generate capabilities settings for you. Simply navigate to that page and select your desired target platform and browser. The capabilities settings will be generated for you and displayed as shown below:

This example shows the capabilities settings for a Chrome browser on the Mac OS X High Sierra Platform. To configure Gwen to use these settings, create a new properties file containing each of the settings above as follows:

file: chrome-mac.properties

gwen.web.capability.os = OS X
gwen.web.capability.os_version = High Sierra
gwen.web.capability.browser = Chrome
gwen.web.capability.browser_version = 67.0
gwen.web.capability.browserstack.local = false
gwen.web.capability.browserstack.selenium_version = 3.11.0

You can save this file anywhere you like. For example, you could save it in your current working directory as chrome-mac.properties.

You can create a separate properties file in the same manner for each other platform, browser, or device you wish to target.

Execution

Now to run your Gwen features on BrowserStack, simply invoke Gwen passing in the above properties file (through the -p option) as follows. This example will run all features in the features/google folder on BrowserStack targeting the Chrome browser on the Mac.

./gwen -b -p chrome-mac.properties features/google

To target a different platform or browser, just pass in the properties file containing those capabilities instead.

If you logon to browserstack.com, you will see the results of all the remotely executed web driver steps and a video recording of the feature execution too.

That’s it!

Gwen Meta = Gherkin Automation Bindings

Declarative Features

From a business perspective, feature specifications should be declarative. What does does this mean? It means that features should describe the intended behavior of a feature independently of any implementation details (especially automation details). They should clearly express behavior in business terms and may also include some examples.

Imperative Features

Imperative specifications on the other hand consist of a step by step list of statements that describe a behavior in great detail and that can be followed robotically to emulate a process. You would ideally never write features in this manner when describing business specifications.

Meta Features

Declarative to Imperative Automation Bindings

Gwen is a Gherkin interpreter that was designed with behavior driven automation (BDA) in mind. It enables teams to bind declarative business features “as is” to imperative meta features to drive automation. Meta features are used to describe (or break down) declarative features into step definitions and bindings that can be used to drive automated testing and robotic processing. In Gwen, they are also defined in the Gherkin language and bind to declarative features at run time to make them executable.

gwen-binding-example

Reuse can be maximised by sharing common meta across features

Test-First

In the test-first approach, the team would first write feature specifications and then use those to drive development and automated testing at the same time. Executing features with Gwen prior to development would result in failures (as expected). As the feature is being implemented in code, the developers and/or testers can write meta features to define all the necessary step definitions and bindings. Loading the meta and executing features with Gwen during development would then enable the test execution to run. By progressively building up the required meta during development, the feature tests will eventually pass when implementation is complete.

Test-Later

In the test-later approach, Gherkin features can be used to drive user acceptance testing after development is complete. New acceptance features can be written if desired at this stage. Any meta that was created during development (if the test-first approach was practiced) could be reused here. Otherwise all the necessary step definitions and bindings would need to be defined in meta during this phase. The meta could then be loaded into Gwen to make the acceptance features perform the test execution.

Robotics

Robotic process automation (RPA) involves the repeatable execution of tasks that would otherwise need to be performed by humans. A repetitive or monotonous process performed online by a person, for example, can be automated with Gwen by writing Gherkin specifications that describe that behavior. These too can be declarative with imperative bindings in meta, but can also be imperative only.

Gwen Web Engine

We have open sourced a web engine (Selenium wrapper) for Gwen that you can use to perform any sort of web UI automation using the approaches described above.

More on Gwen

Gwen for Behavior Driven Automation (BDA)

Gwen is first and foremost a BDA tool. BDD on the other hand has its purpose but it’s not automation. It’s a development practice. But it turns out that behavior in prose can be used to drive automation.

When you use behavioral specifications to drive automation of any kind, you are doing BDA. Be it for testing, robotic process automation (RPA) or any other purpose. It does not matter!

It just so happens that in BDD you are doing it to test-first at development time. In the case of test-later and also RPA, you are doing it after development time. Gwen can be used to transform behavioral specifications into automation operations in any case.

Gwen is about making behavior driven automation easier for everyone.

Core Gwen Interpreter

Web automation engine

Running Gwen Workspaces on Jenkins

In this post I’m going to walk though the basics of getting a Gwen Workspace up and running on Jenkins.

Prerequisites

Be sure you have following setup before proceeding..

  • A running Jenkins environment with
    • Java 1.8+ installed
    • A browser installed (preferably Chrome)

Create a Gwen Workspace Repository

Next, you will need to convert your Gwen project over to a Gwen Workspace. If you have not already done this it is easy to do. Just follow these steps:

  • Download and unzip the latest gwen-workspace.zip to a location on your drive
  • Copy all your .feature and .meta files to the features folder
  • Check that your features execute successfully by running gwen features -b in the workspace root
    • You can tweak any Gwen properties or wrapper scripts in the workspace if required to tailor your execution.
  • Publish your workspace folder to your Git repository

The benefit of using a workspace is that it contains an embedded Gwen Package Manager that will automatically install and configure Gwen for you (so you don’t have to do this manually in the Jenkins environment). If you do not want to use a workspace but would rather utilise your current project setup “as is”, then you will have to do manual installation and configuration work on the Jenkins host to ensure that your features can execute (but the basic setting up of the Jenkins job will be similar to below).

Create a Jenkins Job

Once you have a workspace that is accessible from Git, you are ready to create a Jenkins job to run your workspace.

  • Logon to your Jenkins
  • Create a new “Freestyle” project and give it a name
  • In the “Source Code Management” section, select “Git” and provide your Gwen workspace repository URL and other Git settings
  • In the “Build” section, select “Execute Shell” (for linux) or “Execute Windows Batch Command” (for windows), and enter the following command to run Gwen
    • Linux: ./gwen features -b -f junit -Dgwen.web.browser.headless=true
    • Windows: gwen features -b -f junit -Dgwen.web.browser.headless=true

    -b tells Gwen to exit once execution is complete, -f junit tells Gwen to generate JUnit-XML reports, and -Dgwen.web.browser.headless=true tells Gwen to run the browser in headless mode. You can also pass additional Gwen options if required, like --parallel for example if you want to utilise all cores and perform parallel execution.

  • In the “Post-build Actions” section, select “Publish JUnit test result report”, and enter the following in the “Test Report XMLs” field.
    • target/reports/junit/TEST-*.xml
  • Click “Save” when you are done and then run your job

That’s it!!