Introduction Last updated: 2024-07-10

What is doozer?

Dead simple UI testing framework.

Doozer UI testing framework designed by testers, for testers. It simplifies UI test automation by removing the complexity of writing code with classes, page objects, and other traditional elements. Doozer allows you to easily convert existing manual test scripts into automated tests.

This framework aims to provide a consistent test automation experience across all major platforms. This frees you and your team to focus on more strategic aspects of your work.

Doozer offers a basic scripting language, support for diff-based testing, and a straightforward setup process. Here is an example:

Target audience

Doozer is primarily designed for Testers / Test Engineers who want to automate their workflows but lack extensive experience with coding principles. The framework simplifies the automation process by minimizing technical complexities. It provides a user-friendly scripting language that enables the efficient conversion of existing manual test cases into automated tests.

If you are proficient in using Selenium Webdriver,Cypress, or Playwright, Doozer might not be the optimal choice. These frameworks offer a greater degree of control over test structure compared to Doozer. Consequently, users familiar with these tools might find Doozer's functionality limiting. However, Doozer can be a valuable asset if you find your current testing code overly complex or require a straightforward approach for diff-based UI testing.

Feature set

First release
  • Simple, action based, script language.
  • Diff-based testing with screenshots comparison vs goldens.
  • Semantic Locators support.
  • UI elements assertions.
  • Multiple browsers support.
  • Parallel test execution by default.
  • Detailed logging with failures debugging helpers (window hierarchy + screenshot at fail).
  • Web based image comparison approvals.
  • Syntax highlight in VS Code.

Doozer future

Next steps
  • Support for the following platforms:
    • Android (based on UiAutomator)
  • Custom actions.
  • Support for a11y, l10n and i18n verification.
  • Support for diff-based testing for logs.
  • VS Code code completion.
and after that...
  • Support for the following platforms:
    • iOS (based on XCUITest)
    • Windows (based on WinAppDriver)
  • VS Code debugger.
  • VS Code action recorded.
  • Extend SemanticLocators with Android and iOS implementation.
The prioritization for implementing these features has not yet been finalized. The order will be determined based on user feedback. If you have a strong preference for a particular feature, we encourage you to contact us by email.

Installation

Doozer is built in Java and is distributed as Maven dependency. The Get Started section will guide you through the required setup.

While Doozer scripts can be written using any IDE or text editor, we recommend Visual Studio Code (VSCode) for an enhanced development experience. VSCode offers a syntax highlighting extension specifically designed for the Doozer scripting language. This extension improves code readability and maintainability by visually differentiating keywords, variables, and other code elements.

Prerequisites

Mandatory:

Optional:

Maven dependency

<dependency>
	<groupId>dev.softtest</groupId>
	<artifactId>doozer</artifactId>
	<version>0.2.10</version>
</dependency>

Get Started

This section guides you through the initial steps of developing Doozer tests. Users familiar with Maven can skip the project setup section. We assume you have reviewed the prerequisites section and have already installed the Java SDK and Maven. Let's Begin!

Project setup

  1. Create a new Maven project (source)
    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
    The placeholders com.mycompany.app and my-apprepresent your company's domain and application name, respectively. However, for the sake of this guide, we will use these examples.
    On Windows systems, all command-line parameters must be enclosed in double quotes (").
    The provided command will create a directory named after the artifactId (in this case, my-app). Navigate to this directory and open it in Visual Studio Code (VSCode) if that's your preferred IDE.
  2. Update pom.xml with supported compiler version and check the setup.
    • Open pom.xml
    • Find line: <maven.compiler.source>1.7</maven.compiler.source> and update it with 1.8 instead.
    • Find line: <maven.compiler.target>1.7</maven.compiler.target> and also update it with 1.8.
    • Save the file and run mvn test
    If the command executes successfully, you should observe the following output in your console:
    [INFO] -------------------------------------------------------
    [INFO]  T E S T S
    [INFO] -------------------------------------------------------
    [INFO] Running com.mycompany.app.AppTest
    [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.023 s - in com.mycompany.app.AppTest
    [INFO]
    [INFO] Results:
    [INFO]
    [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
    [INFO]
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  1.856 s
    [INFO] Finished at: 2024-07-18T17:56:16+02:00
    [INFO] ------------------------------------------------------------------------
  3. Add doozer dependency into pom.xml.
    Copy the content of Maven dependency into the dependencies section of your pom.xml file.
  4. Create a base test class - this will be an entry class for your tests, for now it will be empty but in the Codelabs you will learn how to tweak the doozer setup with it. Create a MyDoozerTest.java file in src/test/java/com/mycompany/app/ directory and update it with the following content:
    package com.mycompany.app;
    
    import dev.softtest.doozer.DoozerTest;
    
    public class MyDoozerTest extends DoozerTest {}
  5. Create directory for the tests in src/test/java/com/mycompany/app/, lets call it scripts. You folder structure should look more or less like this now:
    ├── pom.xml
    └── src
        ├── main
        │	└── java
        │	    └── com
        │	        └── mycompany
        │	            └── app
        │	                └── App.java
        └── test
            └── java
                └── com
                    └── mycompany
                        └── app
        	                ├── AppTest.java
        	                ├── MyDoozerTest.java
        	                └── scripts
    App.java and AppTest.java were created by mvn archetype:generate and it is safe to remove them.

Writing first script

  • Create new doozer test
    • Create firstTest directory in src/test/java/com/mycompany/app/scripts/
    • Create goldens directory in src/test/java/com/mycompany/app/scripts/firstTest/
    • Create firstTest.doozer file in src/test/java/com/mycompany/app/scripts/firstTest/
    On linux or macOS this can be done with the following commands:
    mkdir src/test/java/com/mycompany/app/scripts/firstTest
    mkdir src/test/java/com/mycompany/app/scripts/firstTest/goldens
    touch src/test/java/com/mycompany/app/scripts/firstTest/firstTest.doozer
    The folder structure should look like this now:
    (...)
    └── scripts
    	└── firstTest
    		├── firstTest.doozer
    		└── goldens
  • Open firstTest.doozer in VSCode and add your first actions.
    url args:"https://doozer.softtest.dev/test-pages/webform.html"
    type selector:"By.name('name')" args:"Doozer"
    click selector:"By.cssSelector('button')"
    assertInnerText selector:"By.id('message')" args:"Hello Doozer!"
  • Save the changes

Running first script

Now that your test is set up, you can execute it using the mvn testommand along with additional Doozer flags. Open terminal and run the following:

mvn test -Ddoozer.test=src/test/java/com/mycompany/app/scripts/firstTest/firstTest.doozer -Ddoozer.browser=chrome
On Windows systems, you'll need to enclose the Doozer flags within double quotes, here's an example:
mvn test "-Ddoozer.test=src/test/java/com/mycompany/app/scripts/firstTest/firstTest.doozer" "-Ddoozer.browser=chrome"
The mvn test command starts your test that brings up a Chrome browser and executes the test steps. If all went well you should see something like this:
(...)
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.mycompany.app.MyDoozerTest
Running: [1] src/test/java/com/mycompany/app/scripts/firstTest/firstTest.doozer

TestCase                                                                                                 Result   Error
--------                                                                                                 ------   -----
src/test/java/com/mycompany/app/scripts/firstTest/firstTest.doozer                                         PASS
--------                                                                                                 ------   -----
	
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.591 s - in com.mycompany.app.MyDoozerTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  5.441 s
[INFO] Finished at: 2024-07-19T11:32:41+02:00
[INFO] ------------------------------------------------------------------------
The execution results are displayed in your console window. Additionally, they are saved in a dedicated test results directory located at target/doozer-tests/firstTest. This directory contains the following files:
  • doozer-report.html - This HTML report provides a comprehensive overview of all executed test steps, including their status (pass/fail). It's particularly valuable for diff-based testing involving screenshots.
  • doozer.log - This file contains a detailed log of the test execution process.

Congratulations! You've successfully created and executed your first Doozer test.
Now it's time to explore a bit more, in the next sections you'll learn more on running multiple tests in parallel, using screenshots and investigating test failures.
HAPPY TESTING!

Codelabs

Test suite

In this codelab you will learn how to run multiple tests together.

Note

Prerequisites: Java and Maven installed; Project setup from Get Started section is completed.

  1. Create 3 doozer test cases - let's call them firstTest, secondTest and thirdTest.

    Repeat the following steps to create all the three tests, just remember to use a correct name each time:

    • Create firstTest directory in src/test/java/com/mycompany/app/scripts/
    • Create goldens directory in src/test/java/com/mycompany/app/scripts/firstTest/
    • Create firstTest.doozer file in src/test/java/com/mycompany/app/scripts/firstTest/
    On linux or macOS this can be done with the following commands:
    mkdir src/test/java/com/mycompany/app/scripts/firstTest
    mkdir src/test/java/com/mycompany/app/scripts/screenshotTest/goldens
    touch src/test/java/com/mycompany/app/scripts/screenshotTest/firstTest.doozer
    The folder structure should look like this now:
    (...)
    └── scripts
    	└── firstTest
    	│	├── firstTest.doozer
    	│	└── goldens
    	└── secondTest
    	│	├── secondTest.doozer
    	│	└── goldens
    	└── thirdTest
    	 	├── thirdTest.doozer
    	 	└── goldens
  2. Open firstTest.doozer in VSCode and add actions.
    url args:"https://doozer.softtest.dev/test-pages/webform.html"
    type selector:"By.name('name')" args:"Doozer One"
    click selector:"By.cssSelector('button')"
    assertInnerText selector:"By.id('message')" args:"Hello Doozer One!"
    
  3. Open secondTest.doozer in VSCode and add actions.
    url args:"https://doozer.softtest.dev/test-pages/webform.html"
    type selector:"By.name('name')" args:"Doozer Two"
    click selector:"By.cssSelector('button')"
    assertInnerText selector:"By.id('message')" args:"Hello Doozer Two!"
    
  4. Open thirdTest.doozer in VSCode and add actions.
    url args:"https://doozer.softtest.dev/test-pages/webform.html"
    type selector:"By.name('name')" args:"Doozer Three"
    click selector:"By.cssSelector('button')"
    assertInnerText selector:"By.id('message')" args:"Hello Doozer Three!"
    
  5. Run the tests.

    Now, with the test cases ready, you can tell the doozer to run all the tests from a particular directory. This is done by passing a test cases directory in a-Ddoozer.directory flag:

    mvn test -Ddoozer.directory=src/test/java/com/mycompany/app/scripts/ -Ddoozer.browser=chrome
    If everything went well, the tests should pass and you should see the following summary in your console:
    TestCase                                                                      Result   Error               
    --------                                                                      ------   -----               
    src/test/java/com/example/app/examples/firstTest/firstTest.doozer             PASS                       
    src/test/java/com/example/app/examples/secondTest/secondTest.doozer           PASS                       
    src/test/java/com/example/app/examples/thirdTest/thirdTest.doozer             PASS                       
    --------                                                                      ------   -----
  6. In a test suite mode the tests are running in parallel with a dynamic execution strategy. More on that topic you can read at junit doc page.

Golden screenshots

In this codelab you will learn how to take screenshots in a doozer test, how to review the image comparison results and how to update golden files.

Note

Prerequisites: Java and Maven installed; Project setup from Get Started section is completed.

  1. Create new doozer test.
    • Create screenshotTest directory in src/test/java/com/mycompany/app/scripts/
    • Create goldens directory in src/test/java/com/mycompany/app/scripts/firstTest/
    • Create screenshotTest.doozer file in src/test/java/com/mycompany/app/scripts/firstTest/
    On linux or macOS this can be done with the following commands:
    mkdir src/test/java/com/mycompany/app/scripts/screenshotTest
    mkdir src/test/java/com/mycompany/app/scripts/screenshotTest/goldens
    touch src/test/java/com/mycompany/app/scripts/screenshotTest/screenshotTest.doozer
    The folder structure should look like this now:
    (...)
    └── scripts
    	└── screenshotTest
    		├── screenshotTest.doozer
    		└── goldens
  2. Open screenshotTest.doozer in VSCode and add actions..
    url args:"https://doozer.softtest.dev/test-pages/webform.html"
    takeScreenshot args:"empty-form"
  3. Run the test.
    mvn test -Ddoozer.test=src/test/java/com/mycompany/app/scripts/screenshotTest/screenshotTest.doozer -Ddoozer.browser=chrome
  4. Check the results. If everything went well then the test failed with the following error:
    TEST CASE `screenshotTest` FAILED IN ACTION: `takeScreenshot args:"empty-form"` >>> Root cause: Image comparison failed!
    Test execution generated a 'Doozer Test Report' at <WORKING_DIRECTORY>/target/doozer-tests/screenshotTest/doozer-report.html. Open this file in a browser of your choice to review the test result, it should look like this:

    The report shows all the executed test steps, their result and, in case of a takeScreenshot action, a number of pixels the result image differs from the golden one. As we just started, and there is no golden image, we can see that the pixel difference number includes all the pixels in the result image.

  5. Update golden images. Let's assume we would like to use the result image as a golden one, to do this we need to copy it into the goldens directory of the test. The 'Doozer Test Report' page provides a handful functionality supporting this step, do the following:
    • Click APPROVE button, next to the takeScreenshot test step - this will populate a text box at the bottom of the page with a copy command.
    • Click COPY TO CLIPBOARD button, below the text box with commands
    • Paste the clipboard content into the terminal you are running the tests from
    • Done, goldens are updated! You can verify this by checking the content of the goldens in your test case folder.
  6. Re-run the test - this time the execution should be successful.
    mvn test -Ddoozer.test=src/test/java/com/mycompany/app/scripts/screenshotTest/screenshotTest.doozer -Ddoozer.browser=chrome
  7. Add more actions - this time we'll introduce 3 new screenshots.
    type selector:"By.name('name')" args:"Doozer"
    takeScreenshot args:"form-with-data"
    	
    click selector:"By.cssSelector('button')"
    assertInnerText selector:"By.id('message')" args:"Hello Doozer!"
    takeScreenshot args:"form-submitted"
    	
    navigateBack
    clear selector:"By.name('name')"
    type selector:"By.name('name')" args:"Better Doozer"
    click selector:"By.cssSelector('button')"
    takeScreenshot args:"form-resubmitted"
  8. Run the test with a doozer.failOnPixelDiffflag

    In step 7 we introduced 3 more takeScreenshot actions. We could repeat the procedure from 5 but this can become cumbersome when we are creating the test, there are no golden images and the test execution will stop after each image comparison failure. Doozer comes with a handy solution for that problem, you can tell the framework to execute all the test steps, ignoring failures due to image comparison, and then approve the results all at once. To do this you need to run the tests with -Ddoozer.failOnPixelDiff=false flag.

    mvn test -Ddoozer.test=src/test/java/com/mycompany/app/scripts/screenshotTest/screenshotTest.doozer -Ddoozer.browser=chrome -Ddoozer.failOnPixelDiff=false
  9. Check the results.

    Test execution generated a 'Doozer Test Report' at <WORKING_DIRECTORY>/target/doozer-tests/screenshotTest/doozer-report.html. This time you should see 4 takeScreenshot steps, 3 of which (all the added in step 7) have a non-zero pixel difference

  10. Update golden images.

    For each image follow the procedure, like in step 5. In short: click APPROVE button next to the step, copy to clipboard the created command and execute it in your terminal.

  11. Re-run the test - this time without the flag.
    mvn test -Ddoozer.test=src/test/java/com/mycompany/app/scripts/screenshotTest/screenshotTest.doozer -Ddoozer.browser=chrome
  12. Introduce a change causing a failure - to ensure the image comparison mechanism really works.

    Replace "Better Doozer" with "Kermit the Frog"

  13. Run the test.
    mvn test -Ddoozer.test=src/test/java/com/mycompany/app/scripts/screenshotTest/screenshotTest.doozer -Ddoozer.browser=chrome
  14. Check the result - this time the test should fail.

    Open the 'Doozer Test Report' and verify the failure root cause. If all went well, the failure should be in step 15 and should look, more or less, like this:

That's all! You've just learnt how to deal with the screenshots, how to update the golden files, and how to review the results. Hope you've liked this codelab, if you have questions feel free to DM us on X (Twitter) x.com/softtest_dev .

Failures investigation

under development

UI elements identification

under development

Documentation

Actions

List of supported actions

  • Assertions
    • assertCurrentUrl
    • assertInnerText
    • assertPageTitle
  • Interactions
    • alert
    • clear
    • click
    • contextClick
    • deselect
    • doubleClick
    • hover
    • hoverByOffset
    • keyDown
    • keyUp
    • select
    • sendKeys
    • type
  • Navigation
    • navigateBack
    • navigateForward
    • navigateTo
    • refresh
    • url
  • Generics
    • addMask
    • executeScript
    • iframe
    • import
    • set
    • takeScreenshot
    • wait
    • waitForElement

Syntax

Each action within a Doozer script is constructed using three parts, separated by spaces:

  • action name - case sensitive, specifies the operation you want to perform. A list of available actions, along with examples, will be provided later in this section.
  • element selector (optional) - identifies the target element on the web page where the action should be applied. It's prefixed with "selector:" and supports both By and SemanticLocators selectors.
  • action arguments list (optional) - allows you to define additional parameters for the action. It's prefixed with "args:" and consists of key-value pairs separated by commas, for example: "arg1=value1,arg2=value2"

Doozer scripts support two primary modes for specifying selectors and arguments within actions:

Named Parameters (with Prefixes):

  • This mode allows you to explicitly define the selector and arguments using prefixes.
  • It offers flexibility, as you can omit the selector part if an action doesn't require it.

Positional Parameters (without Prefixes):

  • This mode expects both selector and arguments fields to be present, even if the selector is not mandatory for the action.
  • In cases where the selector is not needed, you must include an empty string ("") as a placeholder.

In both modes, selector and args, have to be put inside double quotes.

Usage with named parameters:
actionName selector:"SELECTOR" args:"ARGS"
actionName selector:"SELECTOR"
actionName args:"ARGS"

Usage with positional parameters:
actionName "SELECTOR" "ARGS"
actionName "SELECTOR"
actionName "" "ARGS"

Optional execution - the magic of "?"

Doozer actions provide an optional execution modifier to handle situations where an action might not always be successful. This is particularly useful for elements that appear randomly or are outside your control, such as promotional banners. By appending a question mark (?) to the end of an action name, you mark it as optional. The action will still be executed during the test, but the test will not fail if the action encounters an error. Any failures will be logged with a notice, indicating that the error did not halt the test execution.

click? selector:"SELECTOR"

Special characters in ARGS

In ARGS part, two characters have special meanings: the equals sign "=" and the comma ",". If you want to include these characters within a key-value pair, you need to escape them using a backslash "/" before each character. For example:

pass value with ',':
args:"arg1=value\,with_comma,arg2=value2"

pass value with '='
args:"arg1=value\=with_equals,arg2=value2"

Default parameter in ARGS

When you only need to pass a single parameter, you don't need to define a key=value pair. The framework will automatically assign a default key to the parameter and handle it appropriately. For example:

args:"10" becomes args:"default=10"

Comments

A comment in a doozer script is a line which starts with "//".

// exemplary comment

Actions details

Assertions
  • assertCurrentUrl - asserts current URL. (Selenium Get current URL)
    Parameters:
    - default: expected URL
    
    Syntax:
    assertCurrentUrl args:"PAGE URL"
    
    Named parameters example:
    assertCurrentUrl args:"https://doozer.softtest.dev"
    
    Position based parameters example:
    assertCurrentUrl "" "https://doozer.softtest.dev"
  • assertInnerText - asserts element inner text.
    Parameters:
    - default: expected text
    
    Syntax:
    assertInnerText selector:"SELECTOR" args:"EXPECTED TEXT"
    
    Named parameters example:
    assertInnerText selector:"By.id('my-element')" args:"some text"
    
    Position based parameters example:
    assertInnerText "By.id('my-element')" "some text"
  • assertPageTitle - asserts current page title. (Selenium Get title)
    Parameters:
    - default: expected page title
    
    Syntax:
    assertPageTitle args:"PAGE TITLE"
    
    Named parameters example:
    assertPageTitle args:"doozer"
    
    Position based parameters example:
    assertPageTitle "" "doozer"
Interactions
  • alert- interacts with an alert dialog. (Selenium Alert)
    Parameters:
    - default: confirm | dismiss
    - prompt: a key sequence to send and confirm
    
    Syntax:
    alert args:"CONFIRM or DISMISS"
    alert args:"prompt=KEY_SEQUENCE"
    
    
    Named parameters example:
    alert args:"confirm"
    alert args:"dismiss"
    alert args:"prompt=my-text"
    
    Position based parameters example:
    alert "" "confirm"
    alert "" "dismiss"
    alert "" "prompt=my-text"
  • clear - clears an input element. (Selenium Clear)
    Parameters:
    - none
    
    Syntax:
    clear selector:"SELECTOR"
    
    Named parameters example:
    clear selector:"By.id('my-input')"
    
    Position based parameters example:
    clear "By.id('my-input')"
  • click - clicks on an element. (Selenium Click)
    Parameters:
    - none
    
    Syntax:
    click selector:"SELECTOR"
    
    Named parameters example:
    click selector:"By.id('my-button')"
    
    Position based parameters example:
    click "By.id('my-button')"
  • contextClick - right click on an element. (Selenium Context click (aka right click))
    Parameters:
    - none
    
    Syntax:
    contextClick selector:"SELECTOR"
    
    Named parameters example:
    contextClick selector:"By.id('my-element')"
    
    Position based parameters example:
    contextClick "By.id('my-element')"
  • deselect - deselects an element from a list. (Selenium De-select by visible text)
    Parameters:
    - default: option with text to select
    
    Syntax:
    deselect selector:"SELECTOR" args:"OPTION TEXT"
    
    Named parameters example:
    deselect selector:"By.id('my-list')" args:"option one"
    
    Position based parameters example:
    deselect "By.id('my-list')" "option one"
  • doubleClick - double clicks on an element. (Selenium Double click)
    Parameters:
    - none
    
    Syntax:
    doubleClick selector:"SELECTOR"
    
    Named parameters example:
    doubleClick selector:"By.id('my-element')"
    
    Position based parameters example:
    doubleClick "By.id('my-element')"
  • hover - moves mouse pointer to an element. (Selenium Move to element (aka hover))
    Parameters:
    - none
    
    Syntax:
    hoverByOffset selector:"SELECTOR"
    
    Named parameters example:
    hoverByOffset selector:"By.id('my-element')"
    
    Position based parameters example:
    hoverByOffset "By.id('my-element')"
  • hoverByOffset - moves mouse pointer to an element with given offset. (Selenium Move to element by offset (aka hover by offset))
    Parameters:
    - x - offset from the center point in horizontal direction 
    - y - offset from the center point in vertical direction
    
    Syntax:
    hoverByOffset selector:"SELECTOR" args:"x=X_OFFSET;y=Y_OFFSET"
    
    Named parameters example:
    hoverByOffset selector:"By.id('my-element')" args:"x=30;y=45"
    
    Position based parameters example:
    hoverByOffset "By.id('my-element')" "x=30;y=45"
  • keyDown - presses a key. (Selenium Key down)

    List of accepted key names can be obtained from Keys.java

    Parameters:
    - default: KEY_NAME
    
    Syntax:
    keyDown args:"KEY_NAME"
    
    Named parameters example:
    keyDown args:"SHIFT"
    
    Position based parameters example:
    keyDown "" "SHIFT"
  • keyUp - releases a pressed key. (Selenium Key up)

    List of accepted key names can be obtained from Keys.java

    Parameters:
    - default: KEY_NAME
    
    Syntax:
    keyUp args:"KEY_NAME"
    
    Named parameters example:
    keyUp args:"SHIFT"
    
    Position based parameters example:
    keyUp "" "SHIFT"
  • select - selects an element from a dropdown. (Selenium Select by visible text)
    Parameters:
    - default: option with text to select
    
    Syntax:
    select selector:"SELECTOR" args:"OPTION TEXT"
    
    Named parameters example:
    select selector:"By.id('my-dropdown')" args:"option one"
    
    Position based parameters example:
    select "By.id('my-dropdown')" "option one"
  • sendKeys - sends keys to the current window. (Selenium Send Keys)
    Parameters:
    - default: keys sequence
    
    Syntax:
    sendKeys args:"KEYS SEQUENCE"
    
    Named parameters example:
    sendKeys args:"testing text"
    
    Position based parameters example:
    sendKeys "" "testing text"
  • type - sends keys to the element defined by selector. (Selenium Send Keys)
    Parameters:
    - default: keys sequence
    
    Syntax:
    type selector:"SELECTOR" args:"KEYS SEQUENCE"
    
    Named parameters example:
    type selector:"By.id('my-input')" args:"testing text"
    
    Position based parameters example:
    type "By.id('my-input')" "testing text"
Generics
  • addMask - defines a mask to be used while doing image comparison. The mask is applied to all the following takeScreenshot actions.
    Parameters:
    - default: string to be put in place of the text element defined by selector
    
    Syntax:
    addMask selector:"SELECTOR" args:"MASK_TEXT"
    
    Named parameters example:
    addMask selector:"By.className('date')[0]" args:"2022/01/01 12:13"
    
    Position based parameters example:
    executeScript "By.className('date')[0]" "2022/01/01 12:13"
  • executeScript - executes JS code in current view
    Parameters:
    - default: JS code
    
    Syntax:
    executeScript args:"JavaScript code'"
    
    Named parameters example:
    executeScript args:"document.getElementsByClassName('date')[0].innerHTML\='2000/01/01 12:12'"
    
    Position based parameters example:
    executeScript "" "document.getElementsByClassName('date')[0].innerHTML\='2000/01/01 12:12"
  • iframe - switch to an iframe. Order of execution: selector, parameter - name, parameter - index. If there is no selector nor parameter given, then the action switches to the main iframe on the page. (Selenium Iframes)
    Parameters:
    - name: name of the iframe to switch to
    - index: index of the iframe to switch to
    
    Syntax:
    iframe selector:"SELECTOR"
    iframe args:"name=IFRAME_NAME"
    iframe args:"index=IFRAME_INDEX"
    iframe
    
    Named parameters example:
    iframe selector:"By.tagName('button')"
    iframe args:"index=2"
    
    Position based parameters example:
    iframe "By.tagName('button')"
    iframe "" "index=2"
  • import - includes all the actions from the imported file
    Parameters:
    - default: path to a *.doozer file
    
    Syntax:
    import args:"FILE PATH"
    
    Named parameters example:
    import args:"src/test/java/com/example/commonSteps.doozer"
    
    Position based parameters example:
    import "" "src/test/java/com/example/commonSteps.doozer"
  • set - adds a variable to a test context
    Syntax:
    set name:"VARIABLE NAME" value:"VARIABLE VALUE" 
    
    Named parameters example:
    set name:"google.url" value:"https://www.google.com"
  • takeScreenshot - captures a screenshot of the current browser view and compares it to a reference image.
    • If a filename parameter is not given then the action creates a file with "screenshot-LINE_NUMBER" prefix.
    • Each file with a screenshot is suffixed with a browser string, like 'chrome' or 'chrome-headless'.
    • The action will fail if a system property 'doozer.failOnPixelDiff' is set to 'true' and the image comparison shows differences bigger than accepted threshold (default value is set to 0.01%).
    Parameters:
    - default: filename
    
    Syntax:
    takeScreenshot args:"FILENAME"
    
    Named parameters example:
    takeScreenshot args:"homepage" ==> will create 'homepage-chrome.png' file when running on Chrome
    
    Position based parameters example:
    takeScreenshot "" "homepage"
  • wait - stops test execution for 5 [s] by default
    Parameters:
    - default: wait time in seconds
    
    Syntax:
    wait args:"WAIT TIME IN SECONDS"
    
    Named parameters example:
    wait args:"10"
    
    Position based parameters example:
    import "" "10"
  • waitForElement - waits for a given element to be displayed, by default it waits for 10 [s]. (Selenium Explicit wait)
    Parameters:
    - seconds: wait time in seconds
    
    Syntax:
    waitForElement selector:"SELECTOR" args:"seconds=WAIT TIME IN SECONDS"
    
    Named parameters example:
    waitForElement selector:"By.tagName('button')" args:"seconds=20"
    
    Position based parameters example:
    waitForElement "By.tagName('button')" "seconds=20"

Selectors

  • By.*() - By selectors supported by Selenium
  • Sl() - Semantic locators
  • "" - empty selector, used in positional parameters mode for actions that don't need a selector
If if there is more than one element with the same selector you may choose which one to work with by adding an index as a suffix to the selector string, like this: "By.className('information')[2]" or "Sl({button 'OK'})[0]". The index is 0 based and has to be given in square brackets.
By selectors:
selector:"By.className('information')"
selector:"By.cssSelector('#fname')"
selector:"By.id('lname')"
selector:"By.name('newsletter')"
selector:"By.linkText('Doozer Official Page')"
selector:"By.partialLinkText('Official Page')"
selector:"By.tagName('a')"
selector:"By.xpath('//input[@value=\"f\"]')"

with index:
selector:"By.tagName('a')[2]"

Sematic Locators:
selector:"Sl({button 'OK'})"
selector:"Sl({tab 'Meeting'})"
selector:"Sl({button 'User id: *'})"

with index:
selector:"Sl({button 'OK'})[1]"

Driver setup

Browser

Doozer allows you to choose from several browsers to run your automated tests:

  • Chrome
  • Firefox
  • Edge
  • Safari
Headless Mode Support:

The first three browsers (Chrome, Firefox, and Edge) can be run in headless mode. This means the browser window won't be visible during test execution, improving performance and resource usage.

Specifying a Browser:

To select a browser for your tests, you can use the following command-line flag when running your tests: -Ddoozer.browser=BROWSER Replace BROWSER with the desired browser name (e.g., chrome, firefox, edge, or safari).

Default Browser:

By default, Doozer tests will run in headless Chrome mode (chrome-headless).

Chrome: 	-Ddoozer.browser=chrome 	or 	-Ddoozer.browser=chrome-headless
Firefox: 	-Ddoozer.browser=firefox 	or 	-Ddoozer.browser=firefox-headless
Edge: 		-Ddoozer.browser=edge 		or 	-Ddoozer.browser=edge-headless
Edge: 		-Ddoozer.browser=safari

Window dimensions

Required window size can by defined by overriding setupWindow() method in the test class created at the setup stage.
The default window size is set to 1280 x 700 pixels.

@Override
protected void setupWindow(WebDriver driver) {
	driver.manage().window().setSize(new Dimension(X_DIMENSION_IN_PIXELS, Y_DIMENSION_IN_PIXELS));
}

Implicit timeout

Required implicit timeout can be defined by overriding setupTimeouts() method in the test class created at the setup stage.
The default value is set to 2 [s].

@Override
protected void setupTimeouts(WebDriver driver) {
    driver.manage().timeouts().implicitlyWait(Duration.ofMillis(WAIT_IN_MILLISECONDS));
}

Custom Actions

under development

Configuration flags

-Ddoozer.browser

Defines a browser for a test, default value is "chrome-headless". Read more on Driver setup section.

-Ddoozer.failOnPixelDiff

Controls if a takeScreenshot step fails if image comparison is failing, default value is "true".

-Ddoozer.test

Defines test case to run.

-Ddoozer.directory

Defines directory with test cases to run.

Running the tests

Running a single test case

mvn test -Ddoozer.test=<PATH_TO_THE_DIRECTORY_WITH_TESTS>/TEST_CASE_DIRECTORY/TEST_CASE_FILE.doozer

Example:
mvn test -Ddoozer.test=src/test/java/dev/softtest/doozer/scripts/firstTest/firstTest.doozer

Running all test cases in a directory

mvn test -Ddoozer.directory=<PATH_TO_THE_DIRECTORY_WITH_TESTS>/

Example:
mvn test -Ddoozer.directory=src/test/java/dev/softtest/doozer/scripts/
It is important to keep the "/" at the end of the directory.

Golden images

under development

Test execution logs

under development

Variables

under development

FAQs

All the: 'How can I ...?', 'Is ... supported?' etc.

under development