Gwen 4
Released: 15 November 2024
Gwen 4 introduces launch profiles and a much leaner and more mature automation engine. Redundant features from prior versions have been removed. The internal memory model has been simplified. The execution lifecycle has been solidified. Scalability and security have been strengthened. More code was deleted than added (smaller codebase).
What's New?
Launch Profiles
You can now configure one or many launch profiles, each with its own options and settings. This enables you to configure unique launch configurations for each process in your project so you don't have to manage them externally. You simply give each process a name and define its configuration in a same named settings file in the gwen/conf/profiles
folder of your project. Then when you're ready to launch, you specify the name of the profile you want to run with the -p|--profile
option.
- See profiles for more info.
New Settings
The following settings have been added:
Setting | Description |
---|---|
gwen.input.data.readOnly | Enables or disables read-only mode for all data sourced from input files. Has no effect in REPL mode where read-only is not enforced. |
New Implicits
The following implicit values have been added:
Name | Description |
---|---|
gwen.profile.name | The name of the currently running profile (blank if default) |
New Environment Variables
The following environment variables have been added:
Name | Accepts | Affects CLI option |
---|---|---|
GWEN_PROFILE | Name of profile to launch | -p, --profile |
New DSLs
- Introduced
empty
literal that can be used interchangeably withblank
in all DSL steps whereblank
is accepted. - Introduced
I attach "<filepath>"
DSL for attaching files to Gwen reports (where the name of the attachment will be the name of the file) - Introduced
I log record to <resultsFileId> file
DSL for explicitly logging records to results files
Force Open REPL Option
New --repl command line option added to force open REPL even if the -b|--batch option or feautre files|dirs are specified. This is handy for cases where you might have the batch option or features specified in a launch profile but just want to use the REPL.
Whats Changed?
Changed Runtime Requirements
- Java 17+ is now the minimum supported Java version
- Node 18+ is now the minimum supported Node version
Changed Settings
Deprecated features are now raised as errors by default instead of being logged as warnings.
Setting | Old default | New default |
---|---|---|
gwen.logLevel.deprecations | warn | error |
Changed Project Structure
The env
and browsers
folders have been moved one level down under a conf
subfolder which now also contains a profiles
subfolder where you can define launch profiles.
The new project strucutre looks like this:
./ # Project root
├── README.md
├── gwen.conf # Common settings
└── /gwen
├── .gitignore # Git ignore file
├── /conf
│ ├── /browsers # Browser settings
│ | ├── chrome.conf
│ | ├── edge.conf
│ | ├── firefox.conf
│ | ├── README.md
│ | └── safari.conf
│ ├──/env # Environment settings
│ | ├── dev.conf
│ | ├── local.conf
│ | ├── prod.conf
│ | ├── README.md
│ | ├── staging.conf
│ | └── test.conf
│ └──/profiles # Profile settings
│ ├── README.md
│ ├── profile1.conf
│ ├── profile2.conf
│ ├── ..
│ └── profileN.conf
├── /features # Features (and associative meta)
│ └── README.md
└── /meta # Common meta
└── README.md
Read-Only Input Data
All input data is now read-only at evaluation time by default (except in REPL mode). This can be disabled through the gwen.input.data.readOnly
setting if required.
Associate Meta Always On
The associative meta load stratgy is now always enabled and cannot be disabled. Furthermore, other meta files in the path of the feature are no longer auto-discovered.
Changed Placeholder Syntax in Pattern Matcher
The ignore placeholder syntax in the template matcher has been changed from !{}
to @{*}
.
Also introduced @{**}
to ignore multiple lines.
Changed Logging Implementation
Gwen now uses Logback instead of Log4j for logging . You can override the default logging configuration with your by specifing -Dlogback.configurationFile=/path-to-logback-config-file
on the command line or by setting logback.configurationFile
in your settings file.
What's Deprecated?
Deprecated Settings
The following settings have been deprecated.
Deprecated | Use this instead |
---|---|
gwen.cli.options.batch | gwen.launch.options.batch |
gwen.cli.options.format | gwen.launch.options.format |
gwen.cli.options.inputData | gwen.launch.options.inputData |
gwen.cli.options.dryRun | gwen.launch.options.dryRun |
gwen.cli.options.features | gwen.launch.options.features |
gwen.cli.options.parallel | gwen.launch.options.parallel |
gwen.cli.options.meta | gwen.launch.options.meta |
gwen.cli.options.report | gwen.launch.options.report |
gwen.cli.options.tags | gwen.launch.options.tags |
gwen.feature.failfast | gwen.feature.failfast.enabled |
Deprecated Implicits
The following implicit values have been deprecated.
What's Dropped?
Dropped Integrations
- IE browser integration
- Report Portal integration
- Standalone setup in favor of JS project setup only
- WebDriverManager support in favor of implict SeleniumManager only
Dropped Settings
The following settings have been dropped.
Dropped | Use this instead |
---|---|
gwen-web-accept-untrusted-certs | Use acceptInsecureCerts capability instead |
gwen.auto.discover.data.csv | Use -i/--input launch option instead |
gwen.auto.discover.data.json | Use -i/--input launch option instead |
gwen.auto.discover.meta | Use -m/--meta launch option instead |
gwen.associative.meta | This is now always on |
gwen.web.implicit.js.locators | JS locators |
Dropped DSLs
The following DSLs have been dropped.
I wait <duration> second[s] when <element> is <actioned>
I wait until <condition> when <element> is <actioned>
I navigate to the <page>
I am on the <page>
the <page> url is "<url>"
the url will be "<url>
the url will be defined by <property|setting> "<name>"
- Following deprecated in favour of base steps with
@Timeout
and@Delay
annotations<step> <until|while> <condition> using <delay> <delayUnit> delay
<step> <until|while> <condition> using <timeout> <timeoutUnit> timeout
<step> <until|while> <condition> using <delay> <delayUnit> delay and <timeout> <timeoutUnit> timeout
<step> <until|while> <condition> using no delay and <timeout> <timeoutUnit> timeout
<step> <until|while> <condition> using no delay
<step> <until|while> <condition> using no delay and <timeout> <timeoutUnit> timeout
I wait for <element> for <duration> second[s]
I wait for <element> text for <duration> second[s]
I wait until "<javascript>" using <delay> <delayUnit> delay
I wait until "<javascript>" using <timeout> <timeoutUnit> timeout
I wait until "<javascript>" using <delay> <delayUnit> delay and <timeout> <timeoutUnit> timeout
I wait until <condition> using <delay> <delayUnit> delay
I wait until <condition> using <timeout> <timeoutUnit> timeout
I wait until <condition> using <delay> <delayUnit> delay and <timeout> <timeoutUnit> timeout
<step> for each <element> located by <selector> "<expression>" with no <wait|timeout>
<step> for each <element> located by <selector> "<expression>" with <timeoutSecs> second <wait|timeout>
<step> for each <element> located by <selector> "<expression>" in <containerElement> with no <wait|timeout>
<step> for each <element> located by <selector> "<expression>" in <containerElement> with <timeoutSecs> second <wait|timeout>
<step> <until|while> <element> is[ not] <state> using <delay> <delayUnit> delay
<step> <until|while> <element> is[ not] <state> using <timeout> <timeoutUnit> timeout
<step> <until|while> <element> is[ not] <state> using <delay> <delayUnit> delay and <timeout> <timeoutUnit> timeout
<step> <until|while> <element> is[ not] <state> using no delay and <timeout> <timeoutUnit> timeout
<element> can be located by <selector> "<expression>" with no <wait|timeout>
<step> <until|while> <element> is[ not] <state> using no delay
<step> <until|while> <name> is[ not] defined using <delay> <delayUnit> delay
<step> <until|while> <name> is[ not] defined using <timeout> <timeoutUnit> timeout
<step> <until|while> <name> is[ not] defined using <delay> <delayUnit> delay and <timeout> <timeoutUnit> timeout
<step> <until|while> <name> is[ not] defined using no delay and <timeout> <timeoutUnit> timeout
<step> <until|while> <name> is[ not] defined using no delay
<element> can be located by <selector> "<expression>" with <timeoutSecs> second <wait|timeout>
<element> can be located by <selector> "<expression>" at index <index> with no <wait|timeout>
<element> can be located by <selector> "<expression>" at index <index> with <timeoutSecs> second <wait|timeout>
<element> can be located by <selector> "<expression>" at index <index> in <otherElement> with no <wait|timeout>
<element> can be located by <selector> "<expression>" at index <index> in <otherElement> with <timeoutSecs> second <wait|timeout>
<element> can be located by <selector> "<expression>" <relativeTo> <otherElement> with no <wait|timeout>
<element> can be located by <selector> "<expression>" <relativeTo> <otherElement> with <timeoutSecs> second <wait|timeout>
-
<element> can be located at index <index> with no <wait|timeout> by
| selector | expression |
| <selector 1> | <expression 1> |
| <selector 2> | <expression 2> |
| .. | .. |
| <selector n> | <expression n> | -
<element> can be located at index <index> with <timeoutSecs> second <wait|timeout> by
| selector | expression |
| <selector 1> | <expression 1> |
| <selector 2> | <expression 2> |
| .. | .. |
| <selector n> | <expression n> |