Skip to main content

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.

New Settings

The following settings have been added:

SettingDescription
gwen.input.data.readOnlyEnables 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:

NameDescription
gwen.profile.nameThe name of the currently running profile (blank if default)

New Environment Variables

The following environment variables have been added:

NameAcceptsAffects CLI option
GWEN_PROFILEName of profile to launch-p, --profile

New DSLs

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.

SettingOld defaultNew default
gwen.logLevel.deprecationswarnerror

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.

DeprecatedUse this instead
gwen.cli.options.batchgwen.launch.options.batch
gwen.cli.options.formatgwen.launch.options.format
gwen.cli.options.inputDatagwen.launch.options.inputData
gwen.cli.options.dryRungwen.launch.options.dryRun
gwen.cli.options.featuresgwen.launch.options.features
gwen.cli.options.parallelgwen.launch.options.parallel
gwen.cli.options.metagwen.launch.options.meta
gwen.cli.options.reportgwen.launch.options.report
gwen.cli.options.tagsgwen.launch.options.tags
gwen.feature.failfastgwen.feature.failfast.enabled

Deprecated Implicits

The following implicit values have been deprecated.

DeprecatedUse this instead
gwen.eval.status.keywordgwen.feature.eval.status.keyword
gwen.eval.status.keyword.upperCasedgwen.feature.eval.status.keyword.upperCased
gwen.eval.status.keyword.lowerCasedgwen.feature.eval.status.keyword.lowerCased
gwen.eval.status.keyword.isPassedgwen.feature.eval.status.keyword.isPassed
gwen.eval.status.keyword.isFailedgwen.feature.eval.status.keyword.isFailed
gwen.eval.status.messagegwen.feature.eval.status.message
gwen.eval.status.message.escapedgwen.feature.eval.status.message.escaped
gwen.eval.status.message.csvEscapedgwen.feature.eval.status.message.csvEscaped
gwen.eval.durationgwen.feature.eval.duration
gwen.eval.duration.msecsgwen.feature.eval.duration.msecs
gwen.eval.duration.secsgwen.feature.eval.duration.secs
data record numbergwen.data.record.number
data.record.numbergwen.data.record.number
data.record.indexgwen.data.record.index
record.numbergwen.table.record.number
record.indexgwen.table.record.index
iteration.numbergwen.iteration.number
iteration.indexgwen.iteration.index

What's Dropped?

Dropped Integrations

Dropped Settings

The following settings have been dropped.

DroppedUse this instead
gwen-web-accept-untrusted-certsUse acceptInsecureCerts capability instead
gwen.auto.discover.data.csvUse -i/--input launch option instead
gwen.auto.discover.data.jsonUse -i/--input launch option instead
gwen.auto.discover.metaUse -m/--meta launch option instead
gwen.associative.metaThis is now always on
gwen.web.implicit.js.locatorsJS 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> |