Interacting with elements is something you'd do in every test. ZWL provides easy to use functions and an extensive documentation to help you explorer every possible feature and functionality.
There are mainly two groups of APIs for interacting with elements:
The first group provide functions of type 'do what I mean'
Functions in this group are made for specific and predefined tasks such as 'typing into text field', 'sending keys to page', uploading file etc. A task can be made of multiple internally handled smaller tasks. All edge cases in these tasks are handled so that you get the expected result. This group of APIs don't have specific name but to separate it from the other one we will call it non-action API.
The second group provide functions of type 'do as I say'
Functions in this group are made for composing custom tasks such as 'hover over menu item, hold for a second and move out', 'click, hold and move pointer for X pixels and release' etc. There are no hidden or behind the scene tasks. Only the specified actions are performed, and in the same order they are mentioned. These are helpful for specific pointer and keyboard device related interactions involving series of defined actions. These group of APIs are specifically called Action Api.
Which one should I use?: Depends on what you're trying to accomplish. Action Api must only be used when there is no equivalent function available in non-action API or if there is a requirement of doing series of mouse and/or keyboard device actions.
click(elemId) # clicks on given element clickAll(elemId, elemId, ...) # clicks on all of the given elements clickSwitchNew(elemId)# if a link is clicked, browser moves the focus to the window/tab but# to run further commands on new url, webdriver has to be switched. This# function does that automatically. clickNoSwitch(elemId)# emulates right click. If a link is clicked and browser moves focus to# new tab, this will bring focus to original tab. dblClick(elemId) # clicks on element twice
clear(elemId) clearAll(elemId, elemId, ...) clearActive() # clears the focused element
ZWL has specific functions for typing text into text type fields because it works differently than sending keyboard keys to other elements like document, body or non text type field element. We strongly suggest you use only the designated functions for a particular use to avoid any surprises. ZWL has made sure your key inputs yields the expected results no matter which element on page you want to give input.
type(elemId, keys/string, keys/string, ...)# type given keys or string data into given text type field typeActive(keys/string, keys/string, ...) # type into focused text type field typeIntoElements(string, elemId, elemId, ...) # type the same data into multiple text type fields
The element passed to
type functions should be a text type field such as
The keys or
string passed allows following:
stringdata can include any unicode character such as 'This is going be a 💥'.
- Any modifier or non printable keys (such as
Enter) can be given from
keysconstant. All values in this constant are auto suggested when you press
- When a modifier key is given, it will remain depressed until all non modifier keys have been printed to text field. If you want to release a modifier key in between (such as doing
Enterto switch to next line and releasing Ctrl), pass
keys.nullwhich will release all depressed modifier keys.
- Values in
keysconstant is of type
string. You can even concatenate them with any other
stringdata to make a single string. For example to use in
typeIntoElementsthat accepts only one argument for the data.
type( findElement('description', by.name), 'This starts a new ticket for fixing most', keys.enter, 'designs of the site', keys.shift, ' to increase conversion', keys.tab)
Many applications allow users to trigger actions using keyboard shortcuts. If you need to test keyboard shortcuts on your application, use functions:
sendKeysToPage(elemId, keys, keys, ...) sendKeysToPageF(keys, keys, ...)
sendKeysToPagerequire you to provide an element on page so that the element can be first clicked to get a focus on the page before keys can be sent to it. The element must be a static, visible element with no
jsattached to it so that clicking doesn't trigger any event (such as
header). Note that
bodyelement shouldn't be given as certain browser drivers (webdriver) can't use it for clicking being it's size is 0.
If you know that the page is focused
sendKeysToPageFcan be used that doesn't require an element.
Modifier and non modifier keys can be sent together.
sendKeysToPage(findElement('main', by.role), keys.shift, 'G') # will send Shift + G to page
Utility methods created using Action API.
dragAndDrop(firstElemId, secondElemId) # drags first element over second dragAndDrop(elemId, x, y) # drags element to an offset of x, y
Utility methods created using Action API.
scroll(elemId) # scroll to element scroll(elemId, x, y) # scroll to an offset from element scroll(x, y) # scroll to an offset from current position
Works for only
input[type='file'] elements. Since all Outomated tests runs in a VM, the file to be uploaded from a test need to be stored in the VM locally so that it can be picked from the local file system (just like manual file uploading work in a web page). For this reason, you first need to upload some files using IDE's Upload Test Files screen before you can use their names in tests. See below:
setFile(elemId, fileName) setFiles(elemId, fileName, fileName, ...)
fileName parameter must be the exact name of a file you've previously uploaded from IDE. If you use
setFiles function, the element must be a
multiple attribute and all files given must have already been uploaded from IDE.
You can view and manage all your uploaded files from IDE's Upload Test Files screen as well.
See Api Reference for all available functions in non-action API.
As we discussed in the beginning of this part of documentation, Action API is used for composing custom actions and actions that aren't defined in non-action API. Let's begin with an example to get an overview:
dragAndDrop(elemId, x, y) function we just saw is created using following sequence of action functions:
performAction( move(elemId), hold(), move(x, y), release())
performAction function takes a series of action functions in arguments and executes them in the given order. The sequence of the previous snippet is straight forward and concise. Move the pointer to the element that has to be dragged, hold element using the pointing device, move to the desired offset, release the element. This will perform a drag and drop operation.
Similar to this, any type of sequences can be created using the built-in action functions and they will be executed exactly in the same way as defined.
performAction(...args) function executes a series of action functions provided as arguments. It just executes whatever sequences are given. It is the responsibility of caller to make sure that the sequence is suitable to run in the given order and will perform the desired operation.
Functions that are used to compose an operation and are given as arguments to
performAction. These functions don't do anything on their own unless passed into
performAction. They just provide information about their intended action and any arguments to
performAction. Action functions are of following types:
Action functions that use keyboard device. The following action types define these functions:
Focusing: Before sending keyboard actions to an element, it has to be focused. Use function
focus(elemId)before using any other keyboard related action functions. If this is not done, other keyboard action functions will have no target.
Pressing and releasing modifier keys: ZWL defines all possible action functions for modifier keys that you may require. They are:
altUp(). Use them in sequences to press or release a modifier key whenever you want.
Note that if you don't need to release some depressed modifier keys within the sequence, just leave them depressed. All of them will be automatically released once the action is performed.
Sending non modifier keys: Use function
sendKeys(stringData, stringData, ...)for sending only non modifier keys to the focused element. Don't use this for sending modifier keys and use only the dedicated function described in Pressing and releasing modifier keys because modifier keys will be pressed and released just like non modifier keys with this action function, therefor leaving no effect.
Action functions that use pointing device such as mouse. The following action types define these functions:
Moving: Before doing any pointing actions on an element (such as dragging, hovering), the pointer first has to be moved onto the element. Use one of the following functions before using any other pointer related action functions:
move(elemId): Moves pointer to the center of an element.
move(elemId, x, y): Moves pointer to an offset from element’s center.
move(x, y): Moves pointer to an offset from current position.
Hold & Release: To hold the element (for example to drag) and release it, use functions
Clicking: To click, double click and right click on the element, use functions
clickOnce()(note the suffix 'Once'),
These action functions are for general use and apply to all device types.
pause(milliseconds): Can be used to pause action execution for a given time. For instance, an example action sequence could move a mouse to a menu item and wait for 50 milliseconds before moving again.
Hopefully you get a good knowledge for composing action sequences. It's doesn't just look easy but it's easy to use as well. Look at following use cases:
# A file viewer element shows a 'detail' link on hover. We want to click on that link# to view file details.# To do that, move mouse onto the element and wait for sometime before finding the# detail link and clicking on it.fileViewer = findElement('fileViewer', by.testId)performAction( move(fileViewer), pause(20))linkDetail = findElementFromElement(fileViewer, 'detail', by.text)click(linkDetail)
# An application shows some additional menu on Shift + Ctrl. When we move pointer# over the additional menu, it expands a list. We will then move pointer to a desired# option before clicking on it.performAction( focus(findElement('main', by.role)), shiftDown(), ctrlDown(), move(findElement('fileMenu', by.testId)), move(findElement('Delete Unused Files', by.text)), clickOnce())
performAction can process function arguments defined only in action functions. No other function should be given to it.
See Api Reference for a grater detail to all functions in Action API.