Skip to content

Commit

Permalink
Merge pull request #620 from GuillaumeGomez/wait-for-text-false
Browse files Browse the repository at this point in the history
Add `wait-for-text-false` command
  • Loading branch information
GuillaumeGomez authored Sep 27, 2024
2 parents e5d23cb + 17cf400 commit 69797d0
Show file tree
Hide file tree
Showing 19 changed files with 417 additions and 2 deletions.
31 changes: 31 additions & 0 deletions goml-script.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ Here's the command list:
* [`wait-for-property`](#wait-for-property)
* [`wait-for-property-false`](#wait-for-property-false)
* [`wait-for-text`](#wait-for-text)
* [`wait-for-text-false`](#wait-for-text-false)
* [`wait-for-size`](#wait-for-size)
* [`wait-for-window-property`](#wait-for-window-property)
* [`wait-for-window-property-false`](#wait-for-window-property-false)
Expand Down Expand Up @@ -2297,6 +2298,36 @@ wait-for-text: (".class", "hello", [ALL, CONTAINS])
wait-for-text: (".class", "hello", [ALL, STARTS_WITH, ENDS_WITH])
```

If you want to wait for any of the given element(s) to not have the expected text, take a look at [`wait-for-text-false`](#wait-for-text-false).

#### wait-for-text-false

**wait-for-text-false** command waits for any of the given element(s) to not have the expected text. It'll wait up to 30 seconds by default before failing (can be changed with the [`timeout`](#timeout) command).

Examples:

```
wait-for-text-false: ("#element", "text")
// Same with an XPath:
wait-for-text-false: ("//*[@id='element']", "text")
// If you want to wait for all elements matching this selector/XPath, use `ALL`:
wait-for-text-false: ("#id > .class", "hello", ALL)
wait-for-text-false: ("//*[@id='id']/*[@class='class']", "hello", ALL)
```

Apart from "ALL", you can also use "CONTAINS", "ENDS_WITH" and "STARTS_WITH" and even combine them if you want. Example:

```
wait-for-text-false: (".class", "hello", CONTAINS)
// To wait for all ".class" elements to contain "hello":
wait-for-text-false: (".class", "hello", [ALL, CONTAINS])
// To wait for all ".class" elements to start and end with "hello":
wait-for-text-false: (".class", "hello", [ALL, STARTS_WITH, ENDS_WITH])
```

If you want to wait for the given element(s) to have the expected text, take a look at [`wait-for-text`](#wait-for-text).

#### wait-for-window-property

**wait-for-window-property** command waits for the window objects properties to have the expected values. It'll wait up to 30 seconds by default before failing (can be changed with the [`timeout`](#timeout) command).
Expand Down
2 changes: 2 additions & 0 deletions src/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ const ORDERS = {
'wait-for-property-false': commands.parseWaitForPropertyFalse,
'wait-for-size': commands.parseWaitForSize,
'wait-for-text': commands.parseWaitForText,
'wait-for-text-false': commands.parseWaitForTextFalse,
'wait-for-window-property': commands.parseWaitForWindowProperty,
'wait-for-window-property-false': commands.parseWaitForWindowPropertyFalse,
'write': commands.parseWrite,
Expand Down Expand Up @@ -161,6 +162,7 @@ const FATAL_ERROR_COMMANDS = [
'wait-for-property',
'wait-for-property-false',
'wait-for-text',
'wait-for-text-false',
'write',
'write-into',
];
Expand Down
1 change: 1 addition & 0 deletions src/commands/all.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ module.exports = {
'parseWaitForPropertyFalse': wait.parseWaitForPropertyFalse,
'parseWaitForSize': wait.parseWaitForSize,
'parseWaitForText': wait.parseWaitForText,
'parseWaitForTextFalse': wait.parseWaitForTextFalse,
'parseWaitForWindowProperty': wait.parseWaitForWindowProperty,
'parseWaitForWindowPropertyFalse': wait.parseWaitForWindowPropertyFalse,
'parseWrite': input.parseWrite,
Expand Down
23 changes: 21 additions & 2 deletions src/commands/wait.js
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,17 @@ ${indentString(incr, 1)}
//
// * ("selector", "text")
function parseWaitForText(parser) {
return parseWaitForTextInner(parser, false);
}

// Possible inputs:
//
// * ("selector", "text")
function parseWaitForTextFalse(parser) {
return parseWaitForTextInner(parser, true);
}

function parseWaitForTextInner(parser, waitFalse) {
const identifiers = ['ALL', 'CONTAINS', 'ENDS_WITH', 'STARTS_WITH'];
const ret = validator(parser, {
kind: 'tuple',
Expand Down Expand Up @@ -1045,10 +1056,17 @@ for (const elem of ${varName}) {
}`;
}

let comp = '===';
let errorMessage = '"The following checks still fail: [" + err + "]"';
if (waitFalse) {
comp = '!==';
errorMessage = '"All checks still pass"';
}

const [init, looper] = waitForElement(selector, varName, {checkAll: enabledChecks.has('ALL')});
const incr = incrWait(`\
const err = errors.join(", ");
throw new Error("The following checks still fail: [" + err + "]");`);
throw new Error(${errorMessage});`);

const instructions = `\
${init}
Expand All @@ -1065,7 +1083,7 @@ const value = "${value}";
while (true) {
${indentString(looper, 1)}
${indentString(checker, 1)}
if (errors.length === 0) {
if (errors.length ${comp} 0) {
break;
}
Expand Down Expand Up @@ -1303,6 +1321,7 @@ module.exports = {
'parseWaitForProperty': parseWaitForProperty,
'parseWaitForPropertyFalse': parseWaitForPropertyFalse,
'parseWaitForText': parseWaitForText,
'parseWaitForTextFalse': parseWaitForTextFalse,
'parseWaitForWindowProperty': parseWaitForWindowProperty,
'parseWaitForWindowPropertyFalse': parseWaitForWindowPropertyFalse,
'parseWaitForSize': parseWaitForSize,
Expand Down
53 changes: 53 additions & 0 deletions tests/api-output/parseWaitForTextFalse/basic-1.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
instructions = [
"""const timeLimit = page.getDefaultTimeout();
const timeAdd = 50;
let allTime = 0;
let parseWaitForText = null;
async function checkTextForElem(elem) {
return await elem.evaluate(e => {
const value = \"b\";
const elemText = browserUiTestHelpers.getElemText(e, value);
const errors = [];
if (elemText !== value) {
errors.push(\"`\" + elemText + \"` isn't equal to `\" + value + \"`\");
}
return errors;
});
}
const value = \"b\";
while (true) {
while (true) {
parseWaitForText = await page.$$(\"a\");
if (parseWaitForText.length !== 0) {
parseWaitForText = parseWaitForText[0];
break;
}
await new Promise(r => setTimeout(r, timeAdd));
if (timeLimit === 0) {
continue;
}
allTime += timeAdd;
if (allTime >= timeLimit) {
throw new Error(\"The CSS selector \\\"a\\\" was not found\");
}
}
const errors = await checkTextForElem(parseWaitForText);
if (errors.length !== 0) {
break;
}
await new Promise(r => setTimeout(r, timeAdd));
if (timeLimit === 0) {
continue;
}
allTime += timeAdd;
if (allTime >= timeLimit) {
const err = errors.join(\", \");
throw new Error(\"All checks still pass\");
}
}""",
]
wait = false
warnings = [
]
checkResult = true
54 changes: 54 additions & 0 deletions tests/api-output/parseWaitForTextFalse/basic-2.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
instructions = [
"""const timeLimit = page.getDefaultTimeout();
const timeAdd = 50;
let allTime = 0;
let parseWaitForText = null;
async function checkTextForElem(elem) {
return await elem.evaluate(e => {
const value = \"b\";
const elemText = browserUiTestHelpers.getElemText(e, value);
const errors = [];
if (elemText !== value) {
errors.push(\"`\" + elemText + \"` isn't equal to `\" + value + \"`\");
}
return errors;
});
}
const value = \"b\";
while (true) {
while (true) {
parseWaitForText = await page.$$(\"a\");
if (parseWaitForText.length !== 0) {
parseWaitForText = parseWaitForText[0];
break;
}
await new Promise(r => setTimeout(r, timeAdd));
if (timeLimit === 0) {
continue;
}
allTime += timeAdd;
if (allTime >= timeLimit) {
throw new Error(\"The CSS selector \\\"a\\\" was not found\");
}
}
const errors = await checkTextForElem(parseWaitForText);
if (errors.length !== 0) {
break;
}
await new Promise(r => setTimeout(r, timeAdd));
if (timeLimit === 0) {
continue;
}
allTime += timeAdd;
if (allTime >= timeLimit) {
const err = errors.join(\", \");
throw new Error(\"All checks still pass\");
}
}""",
]
wait = false
warnings = [
"""Pseudo-elements (`::after`) don't have inner text so the check will be performed on the element itself""",
]
checkResult = true
1 change: 1 addition & 0 deletions tests/api-output/parseWaitForTextFalse/err-1.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error = """expected a tuple, found nothing"""
1 change: 1 addition & 0 deletions tests/api-output/parseWaitForTextFalse/err-2.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error = """expected a tuple, found `hello` (an ident)"""
1 change: 1 addition & 0 deletions tests/api-output/parseWaitForTextFalse/err-3.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error = """expected a selector, found `1` (a number) (first element of the tuple)"""
1 change: 1 addition & 0 deletions tests/api-output/parseWaitForTextFalse/err-4.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error = """expected a selector, found `1` (a number) (first element of the tuple)"""
1 change: 1 addition & 0 deletions tests/api-output/parseWaitForTextFalse/err-5.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error = """expected a string, found `2` (a number) (second element of the tuple)"""
1 change: 1 addition & 0 deletions tests/api-output/parseWaitForTextFalse/err-6.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error = """unexpected ident `A` (third element of the tuple). Allowed idents are: [`ALL`, `CONTAINS`, `ENDS_WITH`, `STARTS_WITH`]"""
58 changes: 58 additions & 0 deletions tests/api-output/parseWaitForTextFalse/extra-1.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
instructions = [
"""const timeLimit = page.getDefaultTimeout();
const timeAdd = 50;
let allTime = 0;
let parseWaitForText = null;
async function checkTextForElem(elem) {
return await elem.evaluate(e => {
const value = \"b\";
const elemText = browserUiTestHelpers.getElemText(e, value);
const errors = [];
if (elemText !== value) {
errors.push(\"`\" + elemText + \"` isn't equal to `\" + value + \"`\");
}
return errors;
});
}
const value = \"b\";
while (true) {
while (true) {
parseWaitForText = await page.$$(\"a\");
if (parseWaitForText.length !== 0) {
break;
}
await new Promise(r => setTimeout(r, timeAdd));
if (timeLimit === 0) {
continue;
}
allTime += timeAdd;
if (allTime >= timeLimit) {
throw new Error(\"The CSS selector \\\"a\\\" was not found\");
}
}
let errors = [];
for (const elem of parseWaitForText) {
errors = await checkTextForElem(elem);
if (errors.length !== 0) {
break;
}
}
if (errors.length !== 0) {
break;
}
await new Promise(r => setTimeout(r, timeAdd));
if (timeLimit === 0) {
continue;
}
allTime += timeAdd;
if (allTime >= timeLimit) {
const err = errors.join(\", \");
throw new Error(\"All checks still pass\");
}
}""",
]
wait = false
warnings = [
]
checkResult = true
53 changes: 53 additions & 0 deletions tests/api-output/parseWaitForTextFalse/extra-2.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
instructions = [
"""const timeLimit = page.getDefaultTimeout();
const timeAdd = 50;
let allTime = 0;
let parseWaitForText = null;
async function checkTextForElem(elem) {
return await elem.evaluate(e => {
const value = \"b\";
const elemText = browserUiTestHelpers.getElemText(e, value);
const errors = [];
if (!elemText.includes(value)) {
errors.push(\"`\" + elemText + \"` doesn't contain `\" + value + \"` (for CONTAINS check)\");
}
return errors;
});
}
const value = \"b\";
while (true) {
while (true) {
parseWaitForText = await page.$$(\"a\");
if (parseWaitForText.length !== 0) {
parseWaitForText = parseWaitForText[0];
break;
}
await new Promise(r => setTimeout(r, timeAdd));
if (timeLimit === 0) {
continue;
}
allTime += timeAdd;
if (allTime >= timeLimit) {
throw new Error(\"The CSS selector \\\"a\\\" was not found\");
}
}
const errors = await checkTextForElem(parseWaitForText);
if (errors.length !== 0) {
break;
}
await new Promise(r => setTimeout(r, timeAdd));
if (timeLimit === 0) {
continue;
}
allTime += timeAdd;
if (allTime >= timeLimit) {
const err = errors.join(\", \");
throw new Error(\"All checks still pass\");
}
}""",
]
wait = false
warnings = [
]
checkResult = true
Loading

0 comments on commit 69797d0

Please sign in to comment.