Personal Insights
How to locate controls in UIVeri5 tests
In previous post we have leant how to configure authentication in UIVeri5 tests. In this post you’ll find examples of locators provided by UIVeri5 to simplify test implementation. Here you can read more theory about locators 😊
Introduction
When we automate test cases, we need to locate elements on the page to interact with them. To help us with implementation UIVeri5 has several types of locators. They are discussed below.
Control locator
Control locator is the coolest one 😊 Because it simplifies test implementation significantly. Control locator has the following syntax:
- Locate one element:
element(by.control({
// <matcher properties>
});
- Locate several elements:
element.all(by.control({
// <matcher properties>
});
Where <matcher properties> are:
id: "id"
viewName: "myViewName"
controlType: "UI5 control type" // e.g. "sap.m.ObjectHeader"
bindingPath: {path: "myPath", propertyPath: "myPropertyPath", modelName: "myModelName"}
i18NText: {propertyName: "text", key: "buttonText"}
labelFor: {key: "labelText", modelName: "i18n"}
labelFor: {text: "myText"}
properties: {text: "My Header Text"}
aggregationContainsPropertyEqual: {aggregationName: "myAggregation", propertyName: "enabled", propertyValue: true}
aggregationLengthEquals: {name: "myAggregation", length: 1}
aggregationEmpty: {name: "myAggregation"}
aggregationFilled: {name: "myAggregation"},
ancestor: {id: /^foo/, properties: {text: "My Ancestor Text"}},
descendant: {id: /^bar/, properties: {text: "My Descendant Text"}}
Also you can chain locators: element(by.control({})).element(by.control({}))… or element(by.control({})).all(by.control({}))
Examples:
- Locate sap.m.MultiComboBox with some id:
const multiComboBoxElement= element(by.control({
controlType: "sap.m.MultiComboBox",
id: "multiComboBoxId" , // you can use regular expression here e.g. /ComboBoxId$/
interaction: {idSuffix: "arrow"} // it’s important! Without this property you’ll likely have issues with interactions with sap.m.MultiComboBox.
}));
- Locate sap.m.MultiComboBox in sap.m.HBox which has sap.m.Label with some text
const multiComboBoxElement = element(by.control({
controlType: "sap.m.MultiComboBox",
properties: {enabled: true},
interaction: {idSuffix: "arrow"}, // it’s important! Without this property you’ll likely have issues with interactions with sap.m.MultiComboBox.
ancestor: {
controlType: "sap.m.HBox",
descendant: {
controlType: "sap.m.Label",
properties: {text: "LabelText"}
}
}
}));
- Locate sap.m.Select with some id:
const selectElement = element(by.control({
controlType: "sap.m.Select",
id: "selectId",
interaction: {idSuffix: "arrow"} // it’s important! Without this property you’ll likely have issues with interactions with sap.m.Select.
}));
- Locate sap.m.Switch in sap.m.Toolbar which has sap.m.Label with some text
const configureParametersSwitch = newLandscapePage.element(by.control({
controlType: "sap.m.Switch",
ancestor: {
controlType: "sap.m.Toolbar",
descendant: {
controlType: "sap.m.Label",
properties: {text: "LabelText"}
}
}
}));
- Locate sap.ui.unified.FileUploader and send value to it
const archiveUploadInput = element(by.control({
controlType: "sap.ui.unified.FileUploader"
}));
const absolutePath = path.resolve(__dirname, 'test.txt'); // here you should configure full path to the file
archiveUploadInput.sendKeys(absolutePath);
- Locate sap.ui.unified.MenuTextFieldItem
const filterItem = element(by.control({
controlType: "sap.ui.unified.MenuTextFieldItem",
interaction: {idSuffix: "tf"} // it’s important! Without this property you’ll likely have issues with interactions with sap.ui.unified.MenuTextFieldItem.
}));
- Locate sap.m.DateTimePicker
const fromDatePicker = element(by.control({
controlType: "sap.m.DateTimePicker",
interaction: {idSuffix: "inner"} // it isn’t important.
}));
- Locate sap.m.DateTimePicker by binding properties
const dateTimePicker = element(by.control({
controlType: "sap.m.DateTimePicker",
interaction: {idSuffix: "inner"},
bindingPath: {
modelName: "vm",
propertyPath: "/alertsRangeDateFilter/endDate"
}
}));
- Locate several elements and handle them (example from https://github.com/AnastasyaNN/uiveri5-example)
const changeVersionDialog = element(by.control({
controlType: "sap.m.Dialog",
bindingPath: {
modelName: "appView",
propertyPath: "/bPhoneSize"
}
}));
const versionStandardTreeItems = changeVersionDialog.all(by.control({
controlType: "sap.m.StandardTreeItem",
id: /-versionList-/
}));
versionStandardTreeItems.then(standardTreeItems => {
// here we have array of objects
standardTreeItems.forEach(standardTreeItem => {
// here we work with each object in array and get its property
standardTreeItem.asControl().getProperty("title").then(version => {
if (version === "1.89.0") {
standardTreeItem.click()
}
})
})
});
JQuery locator
JQury locator is quite frequently used in our project. Especially when we need to locate rows in tables. JQuery locator has the following syntax:
element(by.jq(<jquery selector>);
or
element.all(by.jq(<jquery selector>);
Examples:
- Locate all span elements with Expand Node to expand nodes and check
const expandNodeIcons = element.all(by.jq('span[id*="-treeicon"][title="Expand Node"]'));
- Locate row with column value in the table
const objectRow = element(by.jq(`tr[id*="${tableId}-rows"]:has('td:contains("${objectColumnValue}")')`));
- Locate all rows that can be selected
const rows = element.all(by.jq('tr[id*="idCttObjectsTable"][title="Click to Select"]'))
- Locate select all element
const selectAll = element(by.jq(`div[id*="-selall"]`))
CSS locator
CSS locator isn’t used in our project at all. But anyway I think it’s quite useful to know about it. CSS locator has the following syntax:
element(by.css(<css selector>))
Examples:
- Locate elements with some particular class (example from https://github.com/AnastasyaNN/uiveri5-example). Here we check that page is reloaded
browser.driver.wait(function () {
return browser.driver.findElements(by.css('.sapMITHTextContent'))
.then(function (elements) {
return !!elements.length;
});
}, browser.getPageTimeout, 'Waiting for page reload to finish')
// we need to load UI5 dependencies (go to https://github.com/SAP/ui5-uiveri5/blob/master/docs/usage/browser.md for more details)
.then(() => browser.loadUI5Dependencies())
.then(() => …)
Id locator
Id locator isn’t used in our project at all. But it can simplify the development if you know exact Ids. Id locator has the following syntax:
element(by.id(<id>))
Examples:
- Locate element by Id
const changeVersionButton = element(by.id("sdk---app--changeVersionButton"));
Conclusion
UIVeri5 provides several types of locators to simplify test automation. So you can choose the locator for a particular situation to use them more efficient.