Element Interaction
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.
#
NON-ACTION API#
Clicking and double clicking on elementsclick(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 elementclear(elemId)
clearAll(elemId, elemId, ...)
clearActive() # clears the focused element
#
Typing into text type fieldsZWL 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 input[type='text']
, textarea
or contentEditable
elements.
The keys or string
passed allows following:
string
data can include any unicode character such as 'This is going be a 💥'.- Any modifier or non printable keys (such as
Ctrl
,Cmd
,Shift
,Enter
) can be given fromkeys
constant. All values in this constant are auto suggested when you presskeys.
in IDE. - 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
Ctrl
+Enter
to switch to next line and releasing Ctrl), passkeys.null
which will release all depressed modifier keys. - Values in
keys
constant is of typestring
. You can even concatenate them with any otherstring
data to make a single string. For example to use intypeIntoElements
that accepts only one argument for the data.
Example,
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)
#
Testing keyboard shortcutsMany 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, ...)
sendKeysToPage
require 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 nojs
attached to it so that clicking doesn't trigger any event (such asmain
orheader
). Note thatbody
element 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
sendKeysToPageF
can be used that doesn't require an element.Modifier and non modifier keys can be sent together.
Example:
sendKeysToPage(findElement('main', by.role), keys.shift, 'G') # will send Shift + G to page
#
Drag-dropUtility 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
#
ScrollingUtility 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
#
Uploading a file from testWorks 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, ...)
The 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 input[type='file']
with 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.
#
ACTION APIAs 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:
The dragAndDrop(elemId, x, y)
function we just saw is created using following sequence of action functions:
performAction( move(elemId), hold(), move(x, y), release())
The 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.
#
performActionThe 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.
#
action functionsFunctions 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:
#
Keyboard device relatedAction 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:
shiftDown()
,shiftUp()
,ctrlDown()
,ctrlUp()
,cmdDown()
,cmdUp()
,cmdCtrlDown()
,cmdCtrlUp
,altDown()
,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.
#
Pointing device relatedAction 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
hold()
andrelease()
respectively.Clicking: To click, double click and right click on the element, use functions
clickOnce()
(note the suffix 'Once'),doubleClick()
andcontextClick()
respectively.
#
UtilityThese 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.
#
ExamplesHopefully 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())
note
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.