MuseIDE 0.27 release

Summary

New Features

IDE

  • (none)

Framework

  • CutString source can clip a string to a maximum length, from either the beginning or end.
  • The JUnit Report plugin has support for the JUnit Attachments plugin (Jenkins) – see details below.

Enhancements

IDE

  • Combine the Parameters tab, Metadata tab and Event Log into a single area at the bottom of the task editor. The size/location of that area is better remembered
  • In resource editors, move the NotificationPane underneath the button bar so it does not block access to the buttons.
  • Add scrollbar to Task parameters tab
  • Add scrollbar to Browser Providers editor
  • The find multiple parameter on element sources is now part of the expression syntax, to eliminate loss of the parameter during common edits.

Framework

  • Order object properties and map keys alphabetically in the JSON formatted files, for better handling of change-merging and fewer merge conflicts in VCSs.
  • The arguments parameter for a local browser provider is now a value source, instead of a literal. This provides more flexibility in handling multiple environments.

Bug Fixes

IDE

  • Unreadable settings files no longer prevents the IDE from starting
  • The task editor no longer allows steps to be dragged onto themselves or their children.

Framework

  • Fix output paths and misleading error messages in event log from the LocalStorageLocation plugin

JUnit support & Jenkins

This release contains two features for better CI/CD experience in Jenkins.

  1. The main description of a failed task (test) is now the description of the first failure encountered, instead of a summary of the number of failures and errors.
  2. The JUnit Report plugin now supports the Jenkins JUnit Attachments plugin. This provides, for example, quick access to screenshots in the Jenkins UI when troubleshooting failed tests.

To enable the new feature, set the Create Attachment Links option to true in the plugin settings.

Here is an example showing the attachments for this failed test:

MuseIDE 0.26 release

Summary

New Features

IDE

  • Resources in the project navigator can now be organized by folder
  • Task Suite timer can now show hours (for long-running test suites)

Framework

  • SplitString value source added (split a string into a list based on a delimiter)

Enhancements

IDE

  • Resources are sorted in case-insensitive order
  • Improved font rendering on MacOS
  • MacOS installer is now code-signed and notarized for installation on Catalina without errors.

Framework

  • Diagnostic log file renamed to .txt

Bug Fixes

IDE

  • none

Framework

  • Fix the stop() method on the TaskSuiteRunner so that it can interrupt (and stop) a Task from the UI (allowing the task suite to be stopped).

Project sub-folders

By default, project resources are organized by type. For example, the tasks and task suites are grouped together:

NavByType

Now, resources may be organized by their path in the project: main project folder or sub-folders. From the menu in the Navigator view, choose Organize Resource By > Path :

In the muse-examples project, you will see most of the resources are in the project folder, but a few are in the login-tests subfolder:

New resources can be created in new or existing sub-folders when they are created:

Limitations: Currently, there is no support for moving resources from one folder to another within the IDE. This task may be completed directly in the filesystem but the changes will not be reflected in the IDE until the project is re-opened. I recommend:

  1. close the project (to ensure all changes are saved)
  2. make changes in the filesystem
  3. re-open the project

If you create new subfolders in the filesystem containing resources, those folders will not be scanned unless they are added to the .muse/structure.json file. For example:

I hope to add support support moving resources in the near future. And of course, pull requests are always welcome!

Get It

Existing users will receive this update next time you restart the IDE. New users can download the installer from ide4selenium.com.

MuseIDE 0.25 release

Summary

New Features

IDE

  • Add metadata tab with tags, attributes and task description field

Framework

  • ForEach step to iterate over a list of items
  • WithinElement step, which allows executing locators within the children of the specified element
  • ElementAttributeValue to get an attribute value, for example: elementAttribute(element,name)
  • Store Output step and add output storage support in the execution context
  • FilenameFromUrl, TemporaryFilename and TaskFilename value sources
  • ParseJson value source and StoreMapToVariables step
  • Plugin to output test variables to CSV files
  • LocalStorageLocation to the task result
  • optionCount() value source to return the number of options in a Select element
  • Parameterized XPath locator support
  • EvaluateJavascriptSource to run a script in the browser and use the result as the value returned by a ValueSource

Enhancements

IDE

  • add ability to clear breakpoint from the pop-up menu
  • change color of icon to red when breakpoint is set
  • Allow the inline value-source editors to work when there is no initial configuration provided (i.e. creating rather than editing)
  • limit the length of the text displayed for a step to 120 chars
  • Allow ‘.’ character in name UI for general identifiers

Framework

  • Fix variable context for Macros
  • And and Or steps now resolve their parameters progressively, stopping as soon as the outcome is known
  • UnknownStepDescriptor – limit the length of each value source description to 40 chars
  • Better organize the value source types in the UI
  • SendKeys step will accept non-String values in the Keys parameters and convert them to String. Useful primarily for entering integers (numbers)

Bug Fixes

IDE

  • fix concurrency bug in StepTypeSelector
  • sort step types and groups when located, rather doing it in the UI at menu creation time (avoids iteration concurrency problems)

Framework

  • Prevent NPE when debugging and last step in a compound step is removed.
  • ReturnStep is smarter about determining if it is running within a CallFunction step (did not work within PageObjects Actions).
  • empty parameterized test suite hangs the suite execution
  • fix ValueSourceConfiguration.equals() for empty configurations.
  • Add ERROR tag to UserContinueEventType when aborting. This also forces pause in the UI.
  • On MacOS, the drivers (e.g. ChromeDriver and GeckoDriver) need execute permission to run. This fix attempts to set execute permission before running and generates a clear failure if it cannot.

Parameterized XPath Locator

Some will argue that we should not use XPath locators because they are brittle. They are not wrong, but sometimes that is all that is available. When you have to use the same XPath many times, sometimes only with a minor variation, updating those locators when the app changes can be painful. In this example, there are a LOT of XPath locators. Most of them follow a pattern, varying only in a text string.

Annotation 2020-06-06 183155

By using a Parameterized XPath Locator, the duplication is removed. The dozens above were replaced with 4 parameterized locators. As a result, if the page structure changes, at most 4 XPaths need to be changed, instead of dozens from the example above.

In this example, a Parameterized XPath Locator was created (in the Project Navigator) called mp-labeled-select.

Note the new element locator (value source):

<px:"mp-labeled-select":"Place of Origin">
  • px: identifies the type of locator as Parameterized XPath
  • “mp-labeled-select” references the specific Parameterized XPath locator that was created
  • “Place of Origin” is the value that will be substituted into the XPath

The Parameterized XPath Locator was created with this XPath template:

"//p[@class='form-text'][contains(text(), '{0}')]/parent::span/preceding-sibling::select"

Note that “{0]” refers to the first parameter passed from the value source.

Annotation 2020-06-06 200430

Multiple Parameters

Multiple parameters can be passed. In the template, they are referred by their index, for example:

"//p[@class='{0}'][contains(text(), '{1}')]/parent::span/preceding-sibling::{2}"

When using more than one parameter, they must be passed as a list:

<px:"mp-labeled-select":["param1","param2","param3"]>

MuseIDE 0.24 release

Summary

New Features

  • First implementation of support for step breakpoints while running tasks in the IDE (see below)
  • Add Close Window step (closes a window using the window handle)
  • Add Window Handles value source (e.g. <windows>.”length” to count the number of browser windows)

Enhancements

  • Set the correct default value for the Close on Exit parameter of the Open Browser step.

Bug Fixes

  • Improve propagation of Stop button event down to the task execution thread

Breakpoints

Set a breakpoint on a step from the pop-up (context) menu for the step:

breakpoints1

After selecting the Break item from that menu for a step, the task execution will pause before executing the step. Use Play or Step buttons to resume execution.

At this time, there is no indication in the step tree of which steps have a breakpoint set, but you can check a specific step to see if a breakpoint has been set  (note the check mark on the Break item):

breakpoints2

All breakpoints for the task are cleared when the task editor is closed.

Running Muse Tasks in Jenkins

A common use case for MuseIDE is building automated web tests, using Selenium. A common deployment environment for these tests is a CI/CD server, such as Jenkins. This post will show one way to accomplish this. Some of these techniques are applied in the muse-examples project.

Detect Environment

The first problem is: How can Muse detect the environment it is running in?

When Jenkins runs a job, it sets the JOB_NAME environment variable. Muse tasks and plug-ins can access environment variables via a System Value Source. This expression creates a value-source that evaluates to true when running in a Jenkins job:

not(($$"env"."vars"."JOB_NAME") == null)

The hostname can also serve as the decision point. It can also be accessed via the env system value source, such as this example that evaluates to true when running on the buildserver.

$$"env"."hostname" == 'buildserver'

Change Inputs and Outputs

The next problem, is how to change the behavior of the tasks. Two common needs, in handling differences between development and deployment environments, are:

  1. change the URL of the website accessed by a task
  2. change the location of the outputs of a task

Both of these can be solved by injecting values into a task with Variable List and a Variable List Initializer plug-in. There are several possible approaches – here I will describe the approach taken in the muse-examples project.

Step 1 – Create VariableList resources

First, I created 2 VariableList resources – one called project-vars and one called project-vars-local. The first contains general variables for the project and the CI/CD (Jenkins) environment. Note the URL.

varlist-default

The second contains only those that should be different when running locally (i.e. during development of the automation). Note the different URL.

varlist-local

Step 2 – Create Plug-ins

Next, I created two Variable List Initializer plug-ins in the project. The first injects variables from the project-vars list.

initializer-default

The magic happens in the second initializer plug-in. Note the Apply only if parameter. That condition will only run this plug-in if the JOB_NAME environment variable is null…which means when NOT running in Jenkins.

initializer-local

As a result, the URL from the first list will be overwritten from the URL in the second list and the second will be used in local development environment. The first URL will be used when running in Jenkins.

Step 3 – Order the Plug-ins

You may not have noticed that the Apply Automatically? parameter in both of the plug-ins is false, which means they will not be applied to tasks by default. Why? Because by default, there is no implied order that the plug-ins are applied. For many of the plug-ins, that is fine. But in this case, these two must run in the correct order, since the values from one must overwrite the other and not the reverse.

To ensure the order, the Apply Automatically? is turned off and these plug-ins are added to another plug-in, which IS applied automatically. This last plug-in is a List of Plugins, which simply contains a list of other plug-ins to apply. This allows the order of plug-in initialization to be controlled, ensuring that the general variables are applied first and the local variables overwrite them.

list-of-plugins

Note also that the Task Defaults Initializer plug-in runs after both of them. By default, this plug-in will not overwrite existing values, only injecting the defaults if none are present.

Alternate approach

Another approach would be to have only a single variable list initializer plugin that uses an environment variable to choose which list to apply (in the List id parameter). In this example, the list name comes from the INJECT_LIST environment variable.

var-list-env-alternative

This approach has two advantages – (1) using several different lists is easy and (2) plug-in order is irrelevant. The disadvantage is that all required variables need to be included in each list and values that are the same everywhere are duplicated.

 

Standard Output

Muse diagnostic log

By default, the Muse framework writes a diagnostic log to a local file when running a task or task suite.

$home/.muse/muse.log

In a CI/CD environment, this is not convenient. The management tools (Jenkins, etc) will capture the output written to the standard output stream (stdout) and make them conveniently available in the UI for diagnosing problems.

To better integrate into this environment, redirect the Muse diagnostic log to stdout. Two steps are required:

  • provide a logback configuration file that is configured for stdout logging
  • add a command-line option to use the stdout configuration file

These steps are described in the CI/CD Integration section of the user guide.

Muse event logs

Each task (or task suite) produces a separate event log. These can also be echoed to stdout, by configuring the Event Log Writer plugin. Set the //Log to stdout// parameter to true.

event-log-writer-config

Note that this is not a recommend practice for general use. It can be handy for diagnosing problems when you are initially setting up your execution environment, but should be reset to the default (false) when done, for these reasons:

  1. The Muse Automation Framework is designed to be capable of running tasks in parallel. The resulting output would be intermingled…and thus very, very difficult to comprehend.
  2. Failing tasks should be analyzed separately. Reporting plug-ins, such as the JUnit Report plug-in, can include the event log in the report output, making the relevant information conveniently available for each failure.

 

MuseIDE 0.23 release

This is a primarily a maintenance/bugfix release, with a handful of new features.

New Features

  • Selenium Switch To Window – a step for switching to a window by the handle
  • Selenium Switch To New Window – a step for opening a new window and switching to it (and optionally storing the window handle in a variable)
  • Selenium Capture New Window – a compound step for capturing the handle of a window created by a child step
  • Selenium Window handle source – a value source for returning the handle of the current window (e.g. “<window>”).

Maintenance and fixes

  • Re-organize some of the Selenium steps and value-sources in the menus
  • Fix bug in Move Mouse step
  • Expose configurable parameters in Event Logger plugin and add ability to log to stdout
  • Update to logback v1.2.3, which allows re-directing logging via the command-line

MuseIDE 0.22 release

This release brings a few new Selenium steps and a lot of maintenance under-the-covers.

I recently had a great opportunity to help a customer use MuseIDE to author tasks for general desktop automation. As a result, I have started efforts to widen the scope of MuseIDE to more general automation tasks – especially desktop automation and RPA (the framework was always designed to address automation beyond Selenium). As a result, much refactoring has happened under the covers, and this can be seen in the UI as tests are now referred to as tasks.

One side-effect of this change requires that users upgrade the PageObjects extension to 0.4 for compatibility with this release.

Selenium new features

  • Refresh step added
  • Set Browser Position step added
  • Browser Maximize step added
  • Browser Full-screen step added

Improvements

  • Selenium steps re-organized in the step-type menus

Bugs fixed

  • Fixed step-id bug that could cause confusion in the step tree, such as showing the state of the wrong step during debugging

Maintenance

  • Test resource type renamed Task (and TestSuite renamed TaskSuite)
  • internal refactoring (base package name changed from org.musetest to org.museautomation)
  • PageObjects extension upgrade will be required

MuseIDE 0.20 release

This holiday release contains some UI improvements, a few new steps and support for project subfolders. Also, the filename extension for Muse project resources is changing from .json to .muse (see below for more).

Additions and Improvements

UI improvements

  • Resources in the Project Navigator are sorted alphabetically
  • Step types and Value Source types are sorted alphabetically in the chooser drop-down selectors
  • In the Project Navigator, the project name is shown at the top, next to a new close button so you can close a project and open another without closing the IDE
  • Some internal/testing value sources that were visible in the type selectors have now been hidden (these were of no use and therefore confusing to users)
  • When creating a new project resource, the UI will indicate invalid resource names

Step types

  • Else step – for use after an If or Else If step
  • Else If step – for use after an If or Else If step
  • Download File step
  • Delete File step

Value Source types

  • “project-location” system variable added (technically not a value source, but it is accessible via a system variable value source (e.g. $$”project-location”)

Build environment

  • Most projects upgraded to Gradle 6.0
  • Compile target for most projects is Java 11, the latest LTS release (was previously Java 12, which may not fit well within many organizations)

Project Storage

  • The filename extension for project resources will be changing from .json to .muse (see below).
  • Project resources may now be stored in subfolders (see below).

Filename extension change

The filename extension for project resources will be changing from .json to .muse and this release is that start of that process. The reason for this change: I am planning future features that will allow JSON data from local files to be parsed and injected into Muse tasks (tests). Having two very different types of project data stored in files with the same filename extension would be confusing for users and perhaps error-prone for automatic recognition for by the IDE.

  • This release will recognize both extensions (.json and .muse).
  • New resources will be created with the .muse extension
  • Users will be notified of the change when opening projects with resources using the .json filename extension.
  • The notification includes a hint on how to mass-rename files from the command-line.
  • Support for project resources in .json files will be dropped in a future release.

Project sub-folders

Project resources may now be moved into sub-folders. This feature currently has no UI support, but you may make use of this feature by organizing the resources in the filesystem and declaring the relevant project folders for the IDE to scan in a configuration file. The config file, structure.json, should be placed in the .muse subfolder of the project

  1. Organize your files
  2. Create a .muse subfolder in your project folder (if it does not yet exist)
  3. Create a structure.json file in the .muse folder with the contents similar to the example below
  4. Add each folder to the subfolders array, separated by commas
{
"subfolders": ["login-tests","other_folder","etc"]
}

Additional notes:

  • folder structure is not reflected in the UI (yet)
  • resource IDs (i.e. filenames) must still be unique – the folder path is not part of the resource ID (this means you cannot have myresource.muse in multiple folders)
  • sub-folders and sub-sub-folders (etc) are supported, each needs to be listed separately in the config file, as shown below
{
"subfolders": ["folder1","folder1/subfolder1","folder1/subfolder2"]
}

Extension installer authoring

The support for automatic installation of project extensions now supports installation tasks authored within MuseIDE. The use of this feature is currently undocumented – for help with this feature, please contact me.