MOBILE-4110 behat: Allow finding disabled elements
parent
e974912880
commit
a0363deb6a
|
@ -126,14 +126,14 @@ class behat_app extends behat_app_helper {
|
||||||
$containerName = json_encode($containerName);
|
$containerName = json_encode($containerName);
|
||||||
|
|
||||||
$this->spin(function() use ($not, $locator, $containerName) {
|
$this->spin(function() use ($not, $locator, $containerName) {
|
||||||
$result = $this->js("return window.behat.find($locator, $containerName);");
|
$result = $this->js("return window.behat.find($locator, { containerName: $containerName });");
|
||||||
|
|
||||||
if ($not && $result === 'OK') {
|
if ($not && $result === 'OK') {
|
||||||
throw new DriverException('Error, found an item that should not be found');
|
throw new DriverException('Error, found an element that should not be found');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$not && $result !== 'OK') {
|
if (!$not && $result !== 'OK') {
|
||||||
throw new DriverException('Error finding item - ' . $result);
|
throw new DriverException('Error finding element - ' . $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -155,7 +155,7 @@ class behat_app extends behat_app_helper {
|
||||||
$result = $this->js("return window.behat.scrollTo($locator);");
|
$result = $this->js("return window.behat.scrollTo($locator);");
|
||||||
|
|
||||||
if ($result !== 'OK') {
|
if ($result !== 'OK') {
|
||||||
throw new DriverException('Error finding item - ' . $result);
|
throw new DriverException('Error finding element - ' . $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -224,16 +224,16 @@ class behat_app extends behat_app_helper {
|
||||||
switch ($result) {
|
switch ($result) {
|
||||||
case 'YES':
|
case 'YES':
|
||||||
if ($not) {
|
if ($not) {
|
||||||
throw new ExpectationException("Item was selected and shouldn't have", $this->getSession()->getDriver());
|
throw new ExpectationException("Element was selected and shouldn't have", $this->getSession()->getDriver());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'NO':
|
case 'NO':
|
||||||
if (!$not) {
|
if (!$not) {
|
||||||
throw new ExpectationException("Item wasn't selected and should have", $this->getSession()->getDriver());
|
throw new ExpectationException("Element wasn't selected and should have", $this->getSession()->getDriver());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new DriverException('Error finding item - ' . $result);
|
throw new DriverException('Error finding element - ' . $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -536,7 +536,7 @@ class behat_app extends behat_app_helper {
|
||||||
* Clicks on / touches something that is visible in the app.
|
* Clicks on / touches something that is visible in the app.
|
||||||
*
|
*
|
||||||
* Note it is difficult to use the standard 'click on' or 'press' steps because those do not
|
* Note it is difficult to use the standard 'click on' or 'press' steps because those do not
|
||||||
* distinguish visible items and the app always has many non-visible items in the DOM.
|
* distinguish visible elements and the app always has many non-visible elements in the DOM.
|
||||||
*
|
*
|
||||||
* @When /^I press (".+") in the app$/
|
* @When /^I press (".+") in the app$/
|
||||||
* @param string $locator Element locator
|
* @param string $locator Element locator
|
||||||
|
@ -578,6 +578,33 @@ class behat_app extends behat_app_helper {
|
||||||
$this->wait_for_pending_js();
|
$this->wait_for_pending_js();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if elements can be pressed in the app.
|
||||||
|
*
|
||||||
|
* @Then /^I should( not)? be able to press (".+") in the app$/
|
||||||
|
* @param bool $not Whether to assert that the element cannot be pressed
|
||||||
|
* @param string $locator Element locator
|
||||||
|
*/
|
||||||
|
public function i_should_be_able_to_press_in_the_app(bool $not, string $locator) {
|
||||||
|
$locator = $this->parse_element_locator($locator);
|
||||||
|
|
||||||
|
$this->spin(function() use ($not, $locator) {
|
||||||
|
$result = $this->js("return window.behat.find($locator, { onlyClickable: true });");
|
||||||
|
|
||||||
|
if ($not && $result === 'OK') {
|
||||||
|
throw new DriverException('Error, found a clickable element that should not be found');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$not && $result !== 'OK') {
|
||||||
|
throw new DriverException('Error finding clickable element - ' . $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->wait_for_pending_js();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select an item from a list of options, such as a radio button.
|
* Select an item from a list of options, such as a radio button.
|
||||||
*
|
*
|
||||||
|
@ -602,11 +629,11 @@ class behat_app extends behat_app_helper {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Press item.
|
// Press element.
|
||||||
$result = $this->js("return await window.behat.press($locator);");
|
$result = $this->js("return await window.behat.press($locator);");
|
||||||
|
|
||||||
if ($result !== 'OK') {
|
if ($result !== 'OK') {
|
||||||
throw new DriverException('Error pressing item - ' . $result);
|
throw new DriverException('Error pressing element - ' . $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that it worked as expected.
|
// Check that it worked as expected.
|
||||||
|
|
|
@ -45,8 +45,9 @@ Feature: Users can manage entries in database activities
|
||||||
|
|
||||||
Scenario: Browse entry
|
Scenario: Browse entry
|
||||||
Given I entered the data activity "Web links" on course "Course 1" as "student1" in the app
|
Given I entered the data activity "Web links" on course "Course 1" as "student1" in the app
|
||||||
|
|
||||||
# TODO Create and use a generator for database entries.
|
# TODO Create and use a generator for database entries.
|
||||||
And I press "Add entries" in the app
|
When I press "Add entries" in the app
|
||||||
And I set the following fields to these values in the app:
|
And I set the following fields to these values in the app:
|
||||||
| URL | https://moodle.org/ |
|
| URL | https://moodle.org/ |
|
||||||
| Description | Moodle community site |
|
| Description | Moodle community site |
|
||||||
|
@ -59,16 +60,19 @@ Feature: Users can manage entries in database activities
|
||||||
And I press "Save" near "Web links" in the app
|
And I press "Save" near "Web links" in the app
|
||||||
And I press "More" near "Moodle community site" in the app
|
And I press "More" near "Moodle community site" in the app
|
||||||
Then I should find "Moodle community site" in the app
|
Then I should find "Moodle community site" in the app
|
||||||
And I should not find "Next" in the app
|
And I should be able to press "Previous" in the app
|
||||||
And I should find "Previous" in the app
|
But I should not be able to press "Next" in the app
|
||||||
And I press "Previous" in the app
|
|
||||||
And I should find "Moodle Cloud" in the app
|
When I press "Previous" in the app
|
||||||
And I should find "Next" in the app
|
Then I should find "Moodle Cloud" in the app
|
||||||
And I should not find "Previous" in the app
|
And I should be able to press "Next" in the app
|
||||||
And I press "Next" in the app
|
But I should not be able to press "Previous" in the app
|
||||||
And I should find "Moodle community site" in the app
|
|
||||||
And I should not find "Moodle Cloud" in the app
|
When I press "Next" in the app
|
||||||
And I press the back button in the app
|
Then I should find "Moodle community site" in the app
|
||||||
|
But I should not find "Moodle Cloud" in the app
|
||||||
|
|
||||||
|
When I press the back button in the app
|
||||||
And I should find "Moodle community site" in the app
|
And I should find "Moodle community site" in the app
|
||||||
And I should find "Moodle Cloud" in the app
|
And I should find "Moodle Cloud" in the app
|
||||||
|
|
||||||
|
|
|
@ -79,9 +79,14 @@ export class TestingBehatDomUtils {
|
||||||
*
|
*
|
||||||
* @param container Parent element to search the element within
|
* @param container Parent element to search the element within
|
||||||
* @param text Text to look for
|
* @param text Text to look for
|
||||||
|
* @param options Search options.
|
||||||
* @return Elements containing the given text with exact boolean.
|
* @return Elements containing the given text with exact boolean.
|
||||||
*/
|
*/
|
||||||
protected static findElementsBasedOnTextWithinWithExact(container: HTMLElement, text: string): ElementsWithExact[] {
|
protected static findElementsBasedOnTextWithinWithExact(
|
||||||
|
container: HTMLElement,
|
||||||
|
text: string,
|
||||||
|
options: TestingBehatFindOptions,
|
||||||
|
): ElementsWithExact[] {
|
||||||
const attributesSelector = `[aria-label*="${text}"], a[title*="${text}"], img[alt*="${text}"], [placeholder*="${text}"]`;
|
const attributesSelector = `[aria-label*="${text}"], a[title*="${text}"], img[alt*="${text}"], [placeholder*="${text}"]`;
|
||||||
|
|
||||||
const elements = Array.from(container.querySelectorAll<HTMLElement>(attributesSelector))
|
const elements = Array.from(container.querySelectorAll<HTMLElement>(attributesSelector))
|
||||||
|
@ -97,16 +102,23 @@ export class TestingBehatDomUtils {
|
||||||
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_DOCUMENT_FRAGMENT | NodeFilter.SHOW_TEXT, // eslint-disable-line no-bitwise
|
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_DOCUMENT_FRAGMENT | NodeFilter.SHOW_TEXT, // eslint-disable-line no-bitwise
|
||||||
{
|
{
|
||||||
acceptNode: node => {
|
acceptNode: node => {
|
||||||
if (node instanceof HTMLStyleElement ||
|
if (
|
||||||
|
node instanceof HTMLStyleElement ||
|
||||||
node instanceof HTMLLinkElement ||
|
node instanceof HTMLLinkElement ||
|
||||||
node instanceof HTMLScriptElement) {
|
node instanceof HTMLScriptElement
|
||||||
|
) {
|
||||||
return NodeFilter.FILTER_REJECT;
|
return NodeFilter.FILTER_REJECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node instanceof HTMLElement &&
|
if (!(node instanceof HTMLElement)) {
|
||||||
(node.getAttribute('aria-hidden') === 'true' ||
|
return NodeFilter.FILTER_ACCEPT;
|
||||||
node.getAttribute('aria-disabled') === 'true' ||
|
}
|
||||||
getComputedStyle(node).display === 'none')) {
|
|
||||||
|
if (options.onlyClickable && (node.getAttribute('aria-disabled') === 'true' || node.hasAttribute('disabled'))) {
|
||||||
|
return NodeFilter.FILTER_REJECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.getAttribute('aria-hidden') === 'true' || getComputedStyle(node).display === 'none') {
|
||||||
return NodeFilter.FILTER_REJECT;
|
return NodeFilter.FILTER_REJECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +172,7 @@ export class TestingBehatDomUtils {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
elements.push(...this.findElementsBasedOnTextWithinWithExact(childNode, text));
|
elements.push(...this.findElementsBasedOnTextWithinWithExact(childNode, text, options));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,10 +199,15 @@ export class TestingBehatDomUtils {
|
||||||
*
|
*
|
||||||
* @param container Parent element to search the element within.
|
* @param container Parent element to search the element within.
|
||||||
* @param text Text to look for.
|
* @param text Text to look for.
|
||||||
|
* @param options Search options.
|
||||||
* @return Elements containing the given text.
|
* @return Elements containing the given text.
|
||||||
*/
|
*/
|
||||||
protected static findElementsBasedOnTextWithin(container: HTMLElement, text: string): HTMLElement[] {
|
protected static findElementsBasedOnTextWithin(
|
||||||
const elements = this.findElementsBasedOnTextWithinWithExact(container, text);
|
container: HTMLElement,
|
||||||
|
text: string,
|
||||||
|
options: TestingBehatFindOptions,
|
||||||
|
): HTMLElement[] {
|
||||||
|
const elements = this.findElementsBasedOnTextWithinWithExact(container, text, options);
|
||||||
|
|
||||||
// Give more relevance to exact matches.
|
// Give more relevance to exact matches.
|
||||||
elements.sort((a, b) => Number(b.exact) - Number(a.exact));
|
elements.sort((a, b) => Number(b.exact) - Number(a.exact));
|
||||||
|
@ -325,32 +342,33 @@ export class TestingBehatDomUtils {
|
||||||
* Function to find element based on their text or Aria label.
|
* Function to find element based on their text or Aria label.
|
||||||
*
|
*
|
||||||
* @param locator Element locator.
|
* @param locator Element locator.
|
||||||
* @param containerName Whether to search only inside a specific container.
|
* @param options Search options.
|
||||||
* @return First found element.
|
* @return First found element.
|
||||||
*/
|
*/
|
||||||
static findElementBasedOnText(locator: TestingBehatElementLocator, containerName = ''): HTMLElement {
|
static findElementBasedOnText(
|
||||||
return this.findElementsBasedOnText(locator, containerName, true)[0];
|
locator: TestingBehatElementLocator,
|
||||||
|
options: TestingBehatFindOptions,
|
||||||
|
): HTMLElement {
|
||||||
|
return this.findElementsBasedOnText(locator, options)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to find elements based on their text or Aria label.
|
* Function to find elements based on their text or Aria label.
|
||||||
*
|
*
|
||||||
* @param locator Element locator.
|
* @param locator Element locator.
|
||||||
* @param containerName Whether to search only inside a specific container.
|
* @param options Search options.
|
||||||
* @param stopWhenFound Stop looking in containers once an element is found.
|
|
||||||
* @return Found elements
|
* @return Found elements
|
||||||
*/
|
*/
|
||||||
protected static findElementsBasedOnText(
|
protected static findElementsBasedOnText(
|
||||||
locator: TestingBehatElementLocator,
|
locator: TestingBehatElementLocator,
|
||||||
containerName = '',
|
options: TestingBehatFindOptions,
|
||||||
stopWhenFound = false,
|
|
||||||
): HTMLElement[] {
|
): HTMLElement[] {
|
||||||
const topContainers = this.getCurrentTopContainerElements(containerName);
|
const topContainers = this.getCurrentTopContainerElements(options.containerName);
|
||||||
let elements: HTMLElement[] = [];
|
let elements: HTMLElement[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < topContainers.length; i++) {
|
for (let i = 0; i < topContainers.length; i++) {
|
||||||
elements = elements.concat(this.findElementsBasedOnTextInContainer(locator, topContainers[i]));
|
elements = elements.concat(this.findElementsBasedOnTextInContainer(locator, topContainers[i], options));
|
||||||
if (stopWhenFound && elements.length) {
|
if (elements.length) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,16 +381,18 @@ export class TestingBehatDomUtils {
|
||||||
*
|
*
|
||||||
* @param locator Element locator.
|
* @param locator Element locator.
|
||||||
* @param topContainer Container to search in.
|
* @param topContainer Container to search in.
|
||||||
|
* @param options Search options.
|
||||||
* @return Found elements
|
* @return Found elements
|
||||||
*/
|
*/
|
||||||
protected static findElementsBasedOnTextInContainer(
|
protected static findElementsBasedOnTextInContainer(
|
||||||
locator: TestingBehatElementLocator,
|
locator: TestingBehatElementLocator,
|
||||||
topContainer: HTMLElement,
|
topContainer: HTMLElement,
|
||||||
|
options: TestingBehatFindOptions,
|
||||||
): HTMLElement[] {
|
): HTMLElement[] {
|
||||||
let container: HTMLElement | null = topContainer;
|
let container: HTMLElement | null = topContainer;
|
||||||
|
|
||||||
if (locator.within) {
|
if (locator.within) {
|
||||||
const withinElements = this.findElementsBasedOnTextInContainer(locator.within, topContainer);
|
const withinElements = this.findElementsBasedOnTextInContainer(locator.within, topContainer, options);
|
||||||
|
|
||||||
if (withinElements.length === 0) {
|
if (withinElements.length === 0) {
|
||||||
throw new Error('There was no match for within text');
|
throw new Error('There was no match for within text');
|
||||||
|
@ -390,7 +410,10 @@ export class TestingBehatDomUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (topContainer && locator.near) {
|
if (topContainer && locator.near) {
|
||||||
const nearElements = this.findElementsBasedOnTextInContainer(locator.near, topContainer);
|
const nearElements = this.findElementsBasedOnTextInContainer(locator.near, topContainer, {
|
||||||
|
...options,
|
||||||
|
onlyClickable: false,
|
||||||
|
});
|
||||||
|
|
||||||
if (nearElements.length === 0) {
|
if (nearElements.length === 0) {
|
||||||
throw new Error('There was no match for near text');
|
throw new Error('There was no match for near text');
|
||||||
|
@ -412,7 +435,7 @@ export class TestingBehatDomUtils {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const elements = this.findElementsBasedOnTextWithin(container, locator.text);
|
const elements = this.findElementsBasedOnTextWithin(container, locator.text, options);
|
||||||
|
|
||||||
let filteredElements: HTMLElement[] = elements;
|
let filteredElements: HTMLElement[] = elements;
|
||||||
|
|
||||||
|
|
|
@ -153,23 +153,27 @@ export class TestingBehatRuntime {
|
||||||
|
|
||||||
// Find button
|
// Find button
|
||||||
let foundButton: HTMLElement | undefined;
|
let foundButton: HTMLElement | undefined;
|
||||||
|
const options: TestingBehatFindOptions = {
|
||||||
|
onlyClickable: true,
|
||||||
|
containerName: '',
|
||||||
|
};
|
||||||
|
|
||||||
switch (button) {
|
switch (button) {
|
||||||
case 'back':
|
case 'back':
|
||||||
foundButton = TestingBehatDomUtils.findElementBasedOnText({ text: 'Back' });
|
foundButton = TestingBehatDomUtils.findElementBasedOnText({ text: 'Back' }, options);
|
||||||
break;
|
break;
|
||||||
case 'main menu': // Deprecated name.
|
case 'main menu': // Deprecated name.
|
||||||
case 'more menu':
|
case 'more menu':
|
||||||
foundButton = TestingBehatDomUtils.findElementBasedOnText({
|
foundButton = TestingBehatDomUtils.findElementBasedOnText({
|
||||||
text: 'More',
|
text: 'More',
|
||||||
selector: 'ion-tab-button',
|
selector: 'ion-tab-button',
|
||||||
});
|
}, options);
|
||||||
break;
|
break;
|
||||||
case 'user menu' :
|
case 'user menu' :
|
||||||
foundButton = TestingBehatDomUtils.findElementBasedOnText({ text: 'User account' });
|
foundButton = TestingBehatDomUtils.findElementBasedOnText({ text: 'User account' }, options);
|
||||||
break;
|
break;
|
||||||
case 'page menu':
|
case 'page menu':
|
||||||
foundButton = TestingBehatDomUtils.findElementBasedOnText({ text: 'Display options' });
|
foundButton = TestingBehatDomUtils.findElementBasedOnText({ text: 'Display options' }, options);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 'ERROR: Unsupported standard button type';
|
return 'ERROR: Unsupported standard button type';
|
||||||
|
@ -215,20 +219,24 @@ export class TestingBehatRuntime {
|
||||||
* Function to find an arbitrary element based on its text or aria label.
|
* Function to find an arbitrary element based on its text or aria label.
|
||||||
*
|
*
|
||||||
* @param locator Element locator.
|
* @param locator Element locator.
|
||||||
* @param containerName Whether to search only inside a specific container content.
|
* @param options Search options.
|
||||||
* @return OK if successful, or ERROR: followed by message
|
* @return OK if successful, or ERROR: followed by message
|
||||||
*/
|
*/
|
||||||
static find(locator: TestingBehatElementLocator, containerName: string): string {
|
static find(locator: TestingBehatElementLocator, options: Partial<TestingBehatFindOptions> = {}): string {
|
||||||
this.log('Action - Find', { locator, containerName });
|
this.log('Action - Find', { locator, ...options });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const element = TestingBehatDomUtils.findElementBasedOnText(locator, containerName);
|
const element = TestingBehatDomUtils.findElementBasedOnText(locator, {
|
||||||
|
onlyClickable: false,
|
||||||
|
containerName: '',
|
||||||
|
...options,
|
||||||
|
});
|
||||||
|
|
||||||
if (!element) {
|
if (!element) {
|
||||||
return 'ERROR: No element matches locator to find.';
|
return 'ERROR: No element matches locator to find.';
|
||||||
}
|
}
|
||||||
|
|
||||||
this.log('Action - Found', { locator, containerName, element });
|
this.log('Action - Found', { locator, element, ...options });
|
||||||
|
|
||||||
return 'OK';
|
return 'OK';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -246,7 +254,7 @@ export class TestingBehatRuntime {
|
||||||
this.log('Action - scrollTo', { locator });
|
this.log('Action - scrollTo', { locator });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let element = TestingBehatDomUtils.findElementBasedOnText(locator);
|
let element = TestingBehatDomUtils.findElementBasedOnText(locator, { onlyClickable: false, containerName: '' });
|
||||||
|
|
||||||
if (!element) {
|
if (!element) {
|
||||||
return 'ERROR: No element matches element to scroll to.';
|
return 'ERROR: No element matches element to scroll to.';
|
||||||
|
@ -320,7 +328,7 @@ export class TestingBehatRuntime {
|
||||||
this.log('Action - Is Selected', locator);
|
this.log('Action - Is Selected', locator);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const element = TestingBehatDomUtils.findElementBasedOnText(locator);
|
const element = TestingBehatDomUtils.findElementBasedOnText(locator, { onlyClickable: false, containerName: '' });
|
||||||
|
|
||||||
return TestingBehatDomUtils.isElementSelected(element, document.body) ? 'YES' : 'NO';
|
return TestingBehatDomUtils.isElementSelected(element, document.body) ? 'YES' : 'NO';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -338,7 +346,7 @@ export class TestingBehatRuntime {
|
||||||
this.log('Action - Press', locator);
|
this.log('Action - Press', locator);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const found = TestingBehatDomUtils.findElementBasedOnText(locator);
|
const found = TestingBehatDomUtils.findElementBasedOnText(locator, { onlyClickable: true, containerName: '' });
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
return 'ERROR: No element matches locator to press.';
|
return 'ERROR: No element matches locator to press.';
|
||||||
|
@ -421,6 +429,7 @@ export class TestingBehatRuntime {
|
||||||
|
|
||||||
const found: HTMLElement | HTMLInputElement = TestingBehatDomUtils.findElementBasedOnText(
|
const found: HTMLElement | HTMLInputElement = TestingBehatDomUtils.findElementBasedOnText(
|
||||||
{ text: field, selector: 'input, textarea, [contenteditable="true"], ion-select' },
|
{ text: field, selector: 'input, textarea, [contenteditable="true"], ion-select' },
|
||||||
|
{ onlyClickable: false, containerName: '' },
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
|
@ -478,6 +487,11 @@ export type BehatTestsWindow = Window & {
|
||||||
behat?: unknown;
|
behat?: unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type TestingBehatFindOptions = {
|
||||||
|
containerName: string;
|
||||||
|
onlyClickable: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
export type TestingBehatElementLocator = {
|
export type TestingBehatElementLocator = {
|
||||||
text: string;
|
text: string;
|
||||||
within?: TestingBehatElementLocator;
|
within?: TestingBehatElementLocator;
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
@app @javascript
|
||||||
|
Feature: It has a Behat runtime with testing helpers.
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given the following "users" exist:
|
||||||
|
| username |
|
||||||
|
| student1 |
|
||||||
|
|
||||||
|
Scenario: Finds and presses elements
|
||||||
|
Given I entered the app as "student1"
|
||||||
|
When I set the following fields to these values in the app:
|
||||||
|
| Search by activity type or name | Foo bar |
|
||||||
|
Then I should find "Search" "button" in the app
|
||||||
|
And I should find "Clear search" in the app
|
||||||
|
And I should be able to press "Search" "button" in the app
|
||||||
|
But I should not be able to press "Clear search" in the app
|
Loading…
Reference in New Issue