diff --git a/tests/api-output/parseWaitForPropertyFalse/basic-1.toml b/tests/api-output/parseWaitForPropertyFalse/basic-1.toml new file mode 100644 index 000000000..594f38f80 --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/basic-1.toml @@ -0,0 +1,88 @@ +instructions = [ + """async function checkPropForElem(elem) { + return await elem.evaluate(e => { + function checkObjectPaths(object, path, callback, notFoundCallback) { + const found = []; + + for (const subPath of path) { + found.push(subPath); + if (object === undefined || object === null) { + notFoundCallback(found); + return; + } + object = object[subPath]; + } + callback(object); + } + + const nonMatchingProps = []; + const parseWaitForPropDict = []; + const nullProps = []; + for (const prop of nullProps) { + checkObjectPaths(e, prop, val => { + if (val !== undefined && val !== null) { + const p = prop.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Expected property `\" + p + \"` to not exist, found: `\" + val + \"`\"); + return; + } + }, _notFound => { + }); + } + for (const [parseWaitForPropKey, parseWaitForPropValue] of parseWaitForPropDict) { + checkObjectPaths(e, parseWaitForPropKey, val => { + if (val === undefined) { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + return; + } + if (val !== parseWaitForPropValue) { + nonMatchingProps.push(\"expected `\" + parseWaitForPropValue + \"` for property `\" + parseWaitForPropKey + \"`, found `\" + val + \"`\"); + } + }, _notFound => { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + }); + } + return nonMatchingProps; + }); +} + +const timeLimit = page.getDefaultTimeout(); +const timeAdd = 50; +let allTime = 0; +let parseWaitForProp = null; +while (true) { + while (true) { + parseWaitForProp = await page.$$(\"a\"); + if (parseWaitForProp.length !== 0) { + parseWaitForProp = parseWaitForProp[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 nonMatchingProps = await checkPropForElem(parseWaitForProp); + if (nonMatchingProps.length !== 0) { + break; + } + await new Promise(r => setTimeout(r, timeAdd)); + if (timeLimit === 0) { + continue; + } + allTime += timeAdd; + if (allTime >= timeLimit) { + const props = nonMatchingProps.join(\", \"); + throw new Error(\"All properties still match\"); + } +}""", +] +wait = false +warnings = [ +] +checkResult = true diff --git a/tests/api-output/parseWaitForPropertyFalse/basic-2.toml b/tests/api-output/parseWaitForPropertyFalse/basic-2.toml new file mode 100644 index 000000000..91446ac0c --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/basic-2.toml @@ -0,0 +1,88 @@ +instructions = [ + """async function checkPropForElem(elem) { + return await elem.evaluate(e => { + function checkObjectPaths(object, path, callback, notFoundCallback) { + const found = []; + + for (const subPath of path) { + found.push(subPath); + if (object === undefined || object === null) { + notFoundCallback(found); + return; + } + object = object[subPath]; + } + callback(object); + } + + const nonMatchingProps = []; + const parseWaitForPropDict = [[[\"x\"],\"1\"]]; + const nullProps = []; + for (const prop of nullProps) { + checkObjectPaths(e, prop, val => { + if (val !== undefined && val !== null) { + const p = prop.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Expected property `\" + p + \"` to not exist, found: `\" + val + \"`\"); + return; + } + }, _notFound => { + }); + } + for (const [parseWaitForPropKey, parseWaitForPropValue] of parseWaitForPropDict) { + checkObjectPaths(e, parseWaitForPropKey, val => { + if (val === undefined) { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + return; + } + if (val !== parseWaitForPropValue) { + nonMatchingProps.push(\"expected `\" + parseWaitForPropValue + \"` for property `\" + parseWaitForPropKey + \"`, found `\" + val + \"`\"); + } + }, _notFound => { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + }); + } + return nonMatchingProps; + }); +} + +const timeLimit = page.getDefaultTimeout(); +const timeAdd = 50; +let allTime = 0; +let parseWaitForProp = null; +while (true) { + while (true) { + parseWaitForProp = await page.$$(\"a\"); + if (parseWaitForProp.length !== 0) { + parseWaitForProp = parseWaitForProp[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 nonMatchingProps = await checkPropForElem(parseWaitForProp); + if (nonMatchingProps.length !== 0) { + break; + } + await new Promise(r => setTimeout(r, timeAdd)); + if (timeLimit === 0) { + continue; + } + allTime += timeAdd; + if (allTime >= timeLimit) { + const props = nonMatchingProps.join(\", \"); + throw new Error(\"All properties still match\"); + } +}""", +] +wait = false +warnings = [ +] +checkResult = true diff --git a/tests/api-output/parseWaitForPropertyFalse/basic-3.toml b/tests/api-output/parseWaitForPropertyFalse/basic-3.toml new file mode 100644 index 000000000..19411089f --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/basic-3.toml @@ -0,0 +1,88 @@ +instructions = [ + """async function checkPropForElem(elem) { + return await elem.evaluate(e => { + function checkObjectPaths(object, path, callback, notFoundCallback) { + const found = []; + + for (const subPath of path) { + found.push(subPath); + if (object === undefined || object === null) { + notFoundCallback(found); + return; + } + object = object[subPath]; + } + callback(object); + } + + const nonMatchingProps = []; + const parseWaitForPropDict = [[[\"x\"],\"1\"],[[\"y\"],\"2\"]]; + const nullProps = []; + for (const prop of nullProps) { + checkObjectPaths(e, prop, val => { + if (val !== undefined && val !== null) { + const p = prop.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Expected property `\" + p + \"` to not exist, found: `\" + val + \"`\"); + return; + } + }, _notFound => { + }); + } + for (const [parseWaitForPropKey, parseWaitForPropValue] of parseWaitForPropDict) { + checkObjectPaths(e, parseWaitForPropKey, val => { + if (val === undefined) { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + return; + } + if (val !== parseWaitForPropValue) { + nonMatchingProps.push(\"expected `\" + parseWaitForPropValue + \"` for property `\" + parseWaitForPropKey + \"`, found `\" + val + \"`\"); + } + }, _notFound => { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + }); + } + return nonMatchingProps; + }); +} + +const timeLimit = page.getDefaultTimeout(); +const timeAdd = 50; +let allTime = 0; +let parseWaitForProp = null; +while (true) { + while (true) { + parseWaitForProp = await page.$$(\"a\"); + if (parseWaitForProp.length !== 0) { + parseWaitForProp = parseWaitForProp[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 nonMatchingProps = await checkPropForElem(parseWaitForProp); + if (nonMatchingProps.length !== 0) { + break; + } + await new Promise(r => setTimeout(r, timeAdd)); + if (timeLimit === 0) { + continue; + } + allTime += timeAdd; + if (allTime >= timeLimit) { + const props = nonMatchingProps.join(\", \"); + throw new Error(\"All properties still match\"); + } +}""", +] +wait = false +warnings = [ +] +checkResult = true diff --git a/tests/api-output/parseWaitForPropertyFalse/color-1.toml b/tests/api-output/parseWaitForPropertyFalse/color-1.toml new file mode 100644 index 000000000..1e58a8c62 --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/color-1.toml @@ -0,0 +1,88 @@ +instructions = [ + """async function checkPropForElem(elem) { + return await elem.evaluate(e => { + function checkObjectPaths(object, path, callback, notFoundCallback) { + const found = []; + + for (const subPath of path) { + found.push(subPath); + if (object === undefined || object === null) { + notFoundCallback(found); + return; + } + object = object[subPath]; + } + callback(object); + } + + const nonMatchingProps = []; + const parseWaitForPropDict = [[[\"color\"],\"blue\"]]; + const nullProps = []; + for (const prop of nullProps) { + checkObjectPaths(e, prop, val => { + if (val !== undefined && val !== null) { + const p = prop.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Expected property `\" + p + \"` to not exist, found: `\" + val + \"`\"); + return; + } + }, _notFound => { + }); + } + for (const [parseWaitForPropKey, parseWaitForPropValue] of parseWaitForPropDict) { + checkObjectPaths(e, parseWaitForPropKey, val => { + if (val === undefined) { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + return; + } + if (val !== parseWaitForPropValue) { + nonMatchingProps.push(\"expected `\" + parseWaitForPropValue + \"` for property `\" + parseWaitForPropKey + \"`, found `\" + val + \"`\"); + } + }, _notFound => { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + }); + } + return nonMatchingProps; + }); +} + +const timeLimit = page.getDefaultTimeout(); +const timeAdd = 50; +let allTime = 0; +let parseWaitForProp = null; +while (true) { + while (true) { + parseWaitForProp = await page.$$(\"a\"); + if (parseWaitForProp.length !== 0) { + parseWaitForProp = parseWaitForProp[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 nonMatchingProps = await checkPropForElem(parseWaitForProp); + if (nonMatchingProps.length !== 0) { + break; + } + await new Promise(r => setTimeout(r, timeAdd)); + if (timeLimit === 0) { + continue; + } + allTime += timeAdd; + if (allTime >= timeLimit) { + const props = nonMatchingProps.join(\", \"); + throw new Error(\"All properties still match\"); + } +}""", +] +wait = false +warnings = [ +] +checkResult = true diff --git a/tests/api-output/parseWaitForPropertyFalse/err-1.toml b/tests/api-output/parseWaitForPropertyFalse/err-1.toml new file mode 100644 index 000000000..7ebf18c8f --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/err-1.toml @@ -0,0 +1 @@ +error = """expected a tuple, found nothing""" diff --git a/tests/api-output/parseWaitForPropertyFalse/err-2.toml b/tests/api-output/parseWaitForPropertyFalse/err-2.toml new file mode 100644 index 000000000..e5b8f7752 --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/err-2.toml @@ -0,0 +1 @@ +error = """expected a tuple, found `hello` (an ident)""" diff --git a/tests/api-output/parseWaitForPropertyFalse/err-3.toml b/tests/api-output/parseWaitForPropertyFalse/err-3.toml new file mode 100644 index 000000000..ee91ecfef --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/err-3.toml @@ -0,0 +1 @@ +error = """expected a selector, found `1` (a number) (first element of the tuple)""" diff --git a/tests/api-output/parseWaitForPropertyFalse/err-4.toml b/tests/api-output/parseWaitForPropertyFalse/err-4.toml new file mode 100644 index 000000000..ee91ecfef --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/err-4.toml @@ -0,0 +1 @@ +error = """expected a selector, found `1` (a number) (first element of the tuple)""" diff --git a/tests/api-output/parseWaitForPropertyFalse/err-5.toml b/tests/api-output/parseWaitForPropertyFalse/err-5.toml new file mode 100644 index 000000000..41922c8ad --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/err-5.toml @@ -0,0 +1 @@ +error = """expected a JSON dict, found `2` (a number) (second element of the tuple)""" diff --git a/tests/api-output/parseWaitForPropertyFalse/err-6.toml b/tests/api-output/parseWaitForPropertyFalse/err-6.toml new file mode 100644 index 000000000..417bfa3c0 --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/err-6.toml @@ -0,0 +1 @@ +error = """type \"json\" (`{\"a\": 2}`) is not allowed as value in this JSON dict, allowed types are: [`ident`, `number`, `string`] (second element of the tuple)""" diff --git a/tests/api-output/parseWaitForPropertyFalse/err-7.toml b/tests/api-output/parseWaitForPropertyFalse/err-7.toml new file mode 100644 index 000000000..ae42dac3e --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/err-7.toml @@ -0,0 +1 @@ +error = """unexpected ident `a` (third element of the tuple). Allowed idents are: [`ALL`, `CONTAINS`, `ENDS_WITH`, `NEAR`, `STARTS_WITH`]""" diff --git a/tests/api-output/parseWaitForPropertyFalse/extra-1.toml b/tests/api-output/parseWaitForPropertyFalse/extra-1.toml new file mode 100644 index 000000000..097f6de03 --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/extra-1.toml @@ -0,0 +1,94 @@ +instructions = [ + """async function checkPropForElem(elem) { + return await elem.evaluate(e => { + function checkObjectPaths(object, path, callback, notFoundCallback) { + const found = []; + + for (const subPath of path) { + found.push(subPath); + if (object === undefined || object === null) { + notFoundCallback(found); + return; + } + object = object[subPath]; + } + callback(object); + } + + const nonMatchingProps = []; + const parseWaitForPropDict = [[[\"x\"],\"1\"]]; + const nullProps = []; + for (const prop of nullProps) { + checkObjectPaths(e, prop, val => { + if (val !== undefined && val !== null) { + const p = prop.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Expected property `\" + p + \"` to not exist, found: `\" + val + \"`\"); + return; + } + }, _notFound => { + }); + } + for (const [parseWaitForPropKey, parseWaitForPropValue] of parseWaitForPropDict) { + checkObjectPaths(e, parseWaitForPropKey, val => { + if (val === undefined) { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + return; + } + if (val !== parseWaitForPropValue) { + nonMatchingProps.push(\"expected `\" + parseWaitForPropValue + \"` for property `\" + parseWaitForPropKey + \"`, found `\" + val + \"`\"); + } + }, _notFound => { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + }); + } + return nonMatchingProps; + }); +} + +const timeLimit = page.getDefaultTimeout(); +const timeAdd = 50; +let allTime = 0; +let parseWaitForProp = null; +while (true) { + while (true) { + parseWaitForProp = await page.$$(\"a\"); + if (parseWaitForProp.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 nonMatchingProps = []; + for (const elem of parseWaitForProp) { + const ret = await checkPropForElem(elem); + if (ret.length !== 0) { + nonMatchingProps = ret; + break; + } + } + if (nonMatchingProps.length !== 0) { + break; + } + await new Promise(r => setTimeout(r, timeAdd)); + if (timeLimit === 0) { + continue; + } + allTime += timeAdd; + if (allTime >= timeLimit) { + const props = nonMatchingProps.join(\", \"); + throw new Error(\"All properties still match\"); + } +}""", +] +wait = false +warnings = [ +] +checkResult = true diff --git a/tests/api-output/parseWaitForPropertyFalse/extra-2.toml b/tests/api-output/parseWaitForPropertyFalse/extra-2.toml new file mode 100644 index 000000000..67c964756 --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/extra-2.toml @@ -0,0 +1,88 @@ +instructions = [ + """async function checkPropForElem(elem) { + return await elem.evaluate(e => { + function checkObjectPaths(object, path, callback, notFoundCallback) { + const found = []; + + for (const subPath of path) { + found.push(subPath); + if (object === undefined || object === null) { + notFoundCallback(found); + return; + } + object = object[subPath]; + } + callback(object); + } + + const nonMatchingProps = []; + const parseWaitForPropDict = [[[\"x\"],\"1\"]]; + const nullProps = []; + for (const prop of nullProps) { + checkObjectPaths(e, prop, val => { + if (val !== undefined && val !== null) { + const p = prop.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Expected property `\" + p + \"` to not exist, found: `\" + val + \"`\"); + return; + } + }, _notFound => { + }); + } + for (const [parseWaitForPropKey, parseWaitForPropValue] of parseWaitForPropDict) { + checkObjectPaths(e, parseWaitForPropKey, val => { + if (val === undefined) { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + return; + } + if (!val.includes(parseWaitForPropValue)) { + nonMatchingProps.push(\"property `\" + parseWaitForPropKey + \"` (`\" + val + \"`) doesn't contain `\" + parseWaitForPropValue + \"` (for CONTAINS check)\"); + } + }, _notFound => { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + }); + } + return nonMatchingProps; + }); +} + +const timeLimit = page.getDefaultTimeout(); +const timeAdd = 50; +let allTime = 0; +let parseWaitForProp = null; +while (true) { + while (true) { + parseWaitForProp = await page.$$(\"a\"); + if (parseWaitForProp.length !== 0) { + parseWaitForProp = parseWaitForProp[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 nonMatchingProps = await checkPropForElem(parseWaitForProp); + if (nonMatchingProps.length !== 0) { + break; + } + await new Promise(r => setTimeout(r, timeAdd)); + if (timeLimit === 0) { + continue; + } + allTime += timeAdd; + if (allTime >= timeLimit) { + const props = nonMatchingProps.join(\", \"); + throw new Error(\"All properties still match\"); + } +}""", +] +wait = false +warnings = [ +] +checkResult = true diff --git a/tests/api-output/parseWaitForPropertyFalse/extra-3.toml b/tests/api-output/parseWaitForPropertyFalse/extra-3.toml new file mode 100644 index 000000000..bfcb081e4 --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/extra-3.toml @@ -0,0 +1,94 @@ +instructions = [ + """async function checkPropForElem(elem) { + return await elem.evaluate(e => { + function checkObjectPaths(object, path, callback, notFoundCallback) { + const found = []; + + for (const subPath of path) { + found.push(subPath); + if (object === undefined || object === null) { + notFoundCallback(found); + return; + } + object = object[subPath]; + } + callback(object); + } + + const nonMatchingProps = []; + const parseWaitForPropDict = [[[\"x\"],\"1\"]]; + const nullProps = []; + for (const prop of nullProps) { + checkObjectPaths(e, prop, val => { + if (val !== undefined && val !== null) { + const p = prop.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Expected property `\" + p + \"` to not exist, found: `\" + val + \"`\"); + return; + } + }, _notFound => { + }); + } + for (const [parseWaitForPropKey, parseWaitForPropValue] of parseWaitForPropDict) { + checkObjectPaths(e, parseWaitForPropKey, val => { + if (val === undefined) { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + return; + } + if (!val.includes(parseWaitForPropValue)) { + nonMatchingProps.push(\"property `\" + parseWaitForPropKey + \"` (`\" + val + \"`) doesn't contain `\" + parseWaitForPropValue + \"` (for CONTAINS check)\"); + } + }, _notFound => { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + }); + } + return nonMatchingProps; + }); +} + +const timeLimit = page.getDefaultTimeout(); +const timeAdd = 50; +let allTime = 0; +let parseWaitForProp = null; +while (true) { + while (true) { + parseWaitForProp = await page.$$(\"a\"); + if (parseWaitForProp.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 nonMatchingProps = []; + for (const elem of parseWaitForProp) { + const ret = await checkPropForElem(elem); + if (ret.length !== 0) { + nonMatchingProps = ret; + break; + } + } + if (nonMatchingProps.length !== 0) { + break; + } + await new Promise(r => setTimeout(r, timeAdd)); + if (timeLimit === 0) { + continue; + } + allTime += timeAdd; + if (allTime >= timeLimit) { + const props = nonMatchingProps.join(\", \"); + throw new Error(\"All properties still match\"); + } +}""", +] +wait = false +warnings = [ +] +checkResult = true diff --git a/tests/api-output/parseWaitForPropertyFalse/object-path-1.toml b/tests/api-output/parseWaitForPropertyFalse/object-path-1.toml new file mode 100644 index 000000000..706ff08d7 --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/object-path-1.toml @@ -0,0 +1,88 @@ +instructions = [ + """async function checkPropForElem(elem) { + return await elem.evaluate(e => { + function checkObjectPaths(object, path, callback, notFoundCallback) { + const found = []; + + for (const subPath of path) { + found.push(subPath); + if (object === undefined || object === null) { + notFoundCallback(found); + return; + } + object = object[subPath]; + } + callback(object); + } + + const nonMatchingProps = []; + const parseWaitForPropDict = [[[\"x\",\"y\"],\"1\"]]; + const nullProps = []; + for (const prop of nullProps) { + checkObjectPaths(e, prop, val => { + if (val !== undefined && val !== null) { + const p = prop.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Expected property `\" + p + \"` to not exist, found: `\" + val + \"`\"); + return; + } + }, _notFound => { + }); + } + for (const [parseWaitForPropKey, parseWaitForPropValue] of parseWaitForPropDict) { + checkObjectPaths(e, parseWaitForPropKey, val => { + if (val === undefined) { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + return; + } + if (val !== parseWaitForPropValue) { + nonMatchingProps.push(\"expected `\" + parseWaitForPropValue + \"` for property `\" + parseWaitForPropKey + \"`, found `\" + val + \"`\"); + } + }, _notFound => { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + }); + } + return nonMatchingProps; + }); +} + +const timeLimit = page.getDefaultTimeout(); +const timeAdd = 50; +let allTime = 0; +let parseWaitForProp = null; +while (true) { + while (true) { + parseWaitForProp = await page.$$(\"a\"); + if (parseWaitForProp.length !== 0) { + parseWaitForProp = parseWaitForProp[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 nonMatchingProps = await checkPropForElem(parseWaitForProp); + if (nonMatchingProps.length !== 0) { + break; + } + await new Promise(r => setTimeout(r, timeAdd)); + if (timeLimit === 0) { + continue; + } + allTime += timeAdd; + if (allTime >= timeLimit) { + const props = nonMatchingProps.join(\", \"); + throw new Error(\"All properties still match\"); + } +}""", +] +wait = false +warnings = [ +] +checkResult = true diff --git a/tests/api-output/parseWaitForPropertyFalse/object-path-2.toml b/tests/api-output/parseWaitForPropertyFalse/object-path-2.toml new file mode 100644 index 000000000..95e6a466f --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/object-path-2.toml @@ -0,0 +1,88 @@ +instructions = [ + """async function checkPropForElem(elem) { + return await elem.evaluate(e => { + function checkObjectPaths(object, path, callback, notFoundCallback) { + const found = []; + + for (const subPath of path) { + found.push(subPath); + if (object === undefined || object === null) { + notFoundCallback(found); + return; + } + object = object[subPath]; + } + callback(object); + } + + const nonMatchingProps = []; + const parseWaitForPropDict = [[[\"x\",\"y\"],\"1\"],[[\"z\"],\"3\"]]; + const nullProps = []; + for (const prop of nullProps) { + checkObjectPaths(e, prop, val => { + if (val !== undefined && val !== null) { + const p = prop.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Expected property `\" + p + \"` to not exist, found: `\" + val + \"`\"); + return; + } + }, _notFound => { + }); + } + for (const [parseWaitForPropKey, parseWaitForPropValue] of parseWaitForPropDict) { + checkObjectPaths(e, parseWaitForPropKey, val => { + if (val === undefined) { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + return; + } + if (val !== parseWaitForPropValue) { + nonMatchingProps.push(\"expected `\" + parseWaitForPropValue + \"` for property `\" + parseWaitForPropKey + \"`, found `\" + val + \"`\"); + } + }, _notFound => { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + }); + } + return nonMatchingProps; + }); +} + +const timeLimit = page.getDefaultTimeout(); +const timeAdd = 50; +let allTime = 0; +let parseWaitForProp = null; +while (true) { + while (true) { + parseWaitForProp = await page.$$(\"a\"); + if (parseWaitForProp.length !== 0) { + parseWaitForProp = parseWaitForProp[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 nonMatchingProps = await checkPropForElem(parseWaitForProp); + if (nonMatchingProps.length !== 0) { + break; + } + await new Promise(r => setTimeout(r, timeAdd)); + if (timeLimit === 0) { + continue; + } + allTime += timeAdd; + if (allTime >= timeLimit) { + const props = nonMatchingProps.join(\", \"); + throw new Error(\"All properties still match\"); + } +}""", +] +wait = false +warnings = [ +] +checkResult = true diff --git a/tests/api-output/parseWaitForPropertyFalse/pseudo-1.toml b/tests/api-output/parseWaitForPropertyFalse/pseudo-1.toml new file mode 100644 index 000000000..63ad597b2 --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/pseudo-1.toml @@ -0,0 +1,89 @@ +instructions = [ + """async function checkPropForElem(elem) { + return await elem.evaluate(e => { + function checkObjectPaths(object, path, callback, notFoundCallback) { + const found = []; + + for (const subPath of path) { + found.push(subPath); + if (object === undefined || object === null) { + notFoundCallback(found); + return; + } + object = object[subPath]; + } + callback(object); + } + + const nonMatchingProps = []; + const parseWaitForPropDict = [[[\"x\"],\"1\"],[[\"y\"],\"2\"]]; + const nullProps = []; + for (const prop of nullProps) { + checkObjectPaths(e, prop, val => { + if (val !== undefined && val !== null) { + const p = prop.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Expected property `\" + p + \"` to not exist, found: `\" + val + \"`\"); + return; + } + }, _notFound => { + }); + } + for (const [parseWaitForPropKey, parseWaitForPropValue] of parseWaitForPropDict) { + checkObjectPaths(e, parseWaitForPropKey, val => { + if (val === undefined) { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + return; + } + if (val !== parseWaitForPropValue) { + nonMatchingProps.push(\"expected `\" + parseWaitForPropValue + \"` for property `\" + parseWaitForPropKey + \"`, found `\" + val + \"`\"); + } + }, _notFound => { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + }); + } + return nonMatchingProps; + }); +} + +const timeLimit = page.getDefaultTimeout(); +const timeAdd = 50; +let allTime = 0; +let parseWaitForProp = null; +while (true) { + while (true) { + parseWaitForProp = await page.$$(\"a\"); + if (parseWaitForProp.length !== 0) { + parseWaitForProp = parseWaitForProp[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 nonMatchingProps = await checkPropForElem(parseWaitForProp); + if (nonMatchingProps.length !== 0) { + break; + } + await new Promise(r => setTimeout(r, timeAdd)); + if (timeLimit === 0) { + continue; + } + allTime += timeAdd; + if (allTime >= timeLimit) { + const props = nonMatchingProps.join(\", \"); + throw new Error(\"All properties still match\"); + } +}""", +] +wait = false +warnings = [ + """Pseudo-elements (`::after`) don't have properties so the check will be performed on the element itself""", +] +checkResult = true diff --git a/tests/api-output/parseWaitForPropertyFalse/xpath-1.toml b/tests/api-output/parseWaitForPropertyFalse/xpath-1.toml new file mode 100644 index 000000000..4c2caf665 --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/xpath-1.toml @@ -0,0 +1 @@ +error = """XPath must start with `//` (first element of the tuple)""" diff --git a/tests/api-output/parseWaitForPropertyFalse/xpath-2.toml b/tests/api-output/parseWaitForPropertyFalse/xpath-2.toml new file mode 100644 index 000000000..80a1855bc --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/xpath-2.toml @@ -0,0 +1,88 @@ +instructions = [ + """async function checkPropForElem(elem) { + return await elem.evaluate(e => { + function checkObjectPaths(object, path, callback, notFoundCallback) { + const found = []; + + for (const subPath of path) { + found.push(subPath); + if (object === undefined || object === null) { + notFoundCallback(found); + return; + } + object = object[subPath]; + } + callback(object); + } + + const nonMatchingProps = []; + const parseWaitForPropDict = []; + const nullProps = []; + for (const prop of nullProps) { + checkObjectPaths(e, prop, val => { + if (val !== undefined && val !== null) { + const p = prop.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Expected property `\" + p + \"` to not exist, found: `\" + val + \"`\"); + return; + } + }, _notFound => { + }); + } + for (const [parseWaitForPropKey, parseWaitForPropValue] of parseWaitForPropDict) { + checkObjectPaths(e, parseWaitForPropKey, val => { + if (val === undefined) { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + return; + } + if (val !== parseWaitForPropValue) { + nonMatchingProps.push(\"expected `\" + parseWaitForPropValue + \"` for property `\" + parseWaitForPropKey + \"`, found `\" + val + \"`\"); + } + }, _notFound => { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + }); + } + return nonMatchingProps; + }); +} + +const timeLimit = page.getDefaultTimeout(); +const timeAdd = 50; +let allTime = 0; +let parseWaitForProp = null; +while (true) { + while (true) { + parseWaitForProp = await page.$$(\"::-p-xpath(//a)\"); + if (parseWaitForProp.length !== 0) { + parseWaitForProp = parseWaitForProp[0]; + break; + } + await new Promise(r => setTimeout(r, timeAdd)); + if (timeLimit === 0) { + continue; + } + allTime += timeAdd; + if (allTime >= timeLimit) { + throw new Error(\"The XPath \\\"//a\\\" was not found\"); + } + } + const nonMatchingProps = await checkPropForElem(parseWaitForProp); + if (nonMatchingProps.length !== 0) { + break; + } + await new Promise(r => setTimeout(r, timeAdd)); + if (timeLimit === 0) { + continue; + } + allTime += timeAdd; + if (allTime >= timeLimit) { + const props = nonMatchingProps.join(\", \"); + throw new Error(\"All properties still match\"); + } +}""", +] +wait = false +warnings = [ +] +checkResult = true diff --git a/tests/api-output/parseWaitForPropertyFalse/xpath-3.toml b/tests/api-output/parseWaitForPropertyFalse/xpath-3.toml new file mode 100644 index 000000000..a16e835e1 --- /dev/null +++ b/tests/api-output/parseWaitForPropertyFalse/xpath-3.toml @@ -0,0 +1,88 @@ +instructions = [ + """async function checkPropForElem(elem) { + return await elem.evaluate(e => { + function checkObjectPaths(object, path, callback, notFoundCallback) { + const found = []; + + for (const subPath of path) { + found.push(subPath); + if (object === undefined || object === null) { + notFoundCallback(found); + return; + } + object = object[subPath]; + } + callback(object); + } + + const nonMatchingProps = []; + const parseWaitForPropDict = [[[\"x\"],\"1\"]]; + const nullProps = []; + for (const prop of nullProps) { + checkObjectPaths(e, prop, val => { + if (val !== undefined && val !== null) { + const p = prop.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Expected property `\" + p + \"` to not exist, found: `\" + val + \"`\"); + return; + } + }, _notFound => { + }); + } + for (const [parseWaitForPropKey, parseWaitForPropValue] of parseWaitForPropDict) { + checkObjectPaths(e, parseWaitForPropKey, val => { + if (val === undefined) { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + return; + } + if (val !== parseWaitForPropValue) { + nonMatchingProps.push(\"expected `\" + parseWaitForPropValue + \"` for property `\" + parseWaitForPropKey + \"`, found `\" + val + \"`\"); + } + }, _notFound => { + const p = parseWaitForPropKey.map(p => `\"${p}\"`).join('.'); + nonMatchingProps.push(\"Property `\" + p + \"` doesn't exist\"); + }); + } + return nonMatchingProps; + }); +} + +const timeLimit = page.getDefaultTimeout(); +const timeAdd = 50; +let allTime = 0; +let parseWaitForProp = null; +while (true) { + while (true) { + parseWaitForProp = await page.$$(\"::-p-xpath(//a)\"); + if (parseWaitForProp.length !== 0) { + parseWaitForProp = parseWaitForProp[0]; + break; + } + await new Promise(r => setTimeout(r, timeAdd)); + if (timeLimit === 0) { + continue; + } + allTime += timeAdd; + if (allTime >= timeLimit) { + throw new Error(\"The XPath \\\"//a\\\" was not found\"); + } + } + const nonMatchingProps = await checkPropForElem(parseWaitForProp); + if (nonMatchingProps.length !== 0) { + break; + } + await new Promise(r => setTimeout(r, timeAdd)); + if (timeLimit === 0) { + continue; + } + allTime += timeAdd; + if (allTime >= timeLimit) { + const props = nonMatchingProps.join(\", \"); + throw new Error(\"All properties still match\"); + } +}""", +] +wait = false +warnings = [ +] +checkResult = true diff --git a/tests/ui/wait-for-property-false.goml b/tests/ui/wait-for-property-false.goml new file mode 100644 index 000000000..12b9389c3 --- /dev/null +++ b/tests/ui/wait-for-property-false.goml @@ -0,0 +1,23 @@ +// This test ensures that the `wait-for-property-false` command is behaving like expected. +screenshot-comparison: false +go-to: "file://" + |CURRENT_DIR| + "/" + |DOC_PATH| + "/elements.html" +set-timeout: 400 +// Shouldn't wait here since it's already the case. +wait-for-property-false: ("#js-wait-prop", {"hehe": "haha"}) +click: "#js-wait-prop" +// Should wait for 250ms here. +wait-for-property-false: ("#js-wait-prop", {"someProp": null}) +click: "#js-create-elem" +// Should wait for 100ms here (the element is created first). +wait-for-property-false: ("#created-one", {"hehe": null}) + +// object-path +assert-property: ("#js-wait-prop2", {"toto"."z": null}) +click: "#js-wait-prop2" +// Should wait for 100ms here. +wait-for-property-false: ("#js-wait-prop2", {"toto"."z": null}) + +// This next one should fail. +wait-for-property-false: ("#js-wait-prop", {"hehe": "hoho"}) +// Check that the script won't run anything after the previous command failed. +assert-property: ("#js-wait-prop", {"data-a": "c"}) diff --git a/tests/ui/wait-for-property-false.output b/tests/ui/wait-for-property-false.output new file mode 100644 index 000000000..9b42c8a8c --- /dev/null +++ b/tests/ui/wait-for-property-false.output @@ -0,0 +1,7 @@ +=> Starting doc-ui tests... + +wait-for-property-false... FAILED +[ERROR] `tests/ui/wait-for-property-false.goml` line 21: Error: All properties still match: for command `wait-for-property-false: ("#js-wait-prop", {"hehe": "hoho"})` + + +<= doc-ui tests done: 0 succeeded, 1 failed \ No newline at end of file diff --git a/tests/ui/wait-for-property.goml b/tests/ui/wait-for-property.goml index fd766663b..c187117fa 100644 --- a/tests/ui/wait-for-property.goml +++ b/tests/ui/wait-for-property.goml @@ -10,6 +10,13 @@ wait-for-property: ("#js-wait-prop", {"someProp": "hello"}) click: "#js-create-elem" // Should wait for 100ms here (the element is created first). wait-for-property: ("#created-one", {"hehe": "hoho"}) + +// object-path +assert-property: ("#js-wait-prop2", {"toto"."z": null}) +click: "#js-wait-prop2" +// Should wait for 100ms here. +wait-for-property: ("#js-wait-prop2", {"toto"."z": 78}) + // This next one should fail. wait-for-property: ("#js-wait-prop", {"data-a": "c"}) // Check that the script won't run anything after the previous command failed. diff --git a/tests/ui/wait-for-property.output b/tests/ui/wait-for-property.output index 82423ee57..18fc28809 100644 --- a/tests/ui/wait-for-property.output +++ b/tests/ui/wait-for-property.output @@ -1,7 +1,7 @@ => Starting doc-ui tests... wait-for-property... FAILED -[ERROR] `tests/ui/wait-for-property.goml` line 14: Error: The following properties still don't match: [Property `"data-a"` doesn't exist]: for command `wait-for-property: ("#js-wait-prop", {"data-a": "c"})` +[ERROR] `tests/ui/wait-for-property.goml` line 18: Error: The following properties still don't match: [expected `78` for property `toto,z`, found `78`]: for command `wait-for-property: ("#js-wait-prop2", {"toto"."z": 78})` <= doc-ui tests done: 0 succeeded, 1 failed \ No newline at end of file diff --git a/tools/api.js b/tools/api.js index dbb86a238..108b37e73 100644 --- a/tools/api.js +++ b/tools/api.js @@ -2913,6 +2913,11 @@ const TO_CHECK = [ 'func': checkWaitForProperty, 'toCall': (x, e, name, o) => wrapper(parserFuncs.parseWaitForProperty, x, e, name, o), }, + { + 'name': 'wait-for-property-false', + 'func': checkWaitForProperty, + 'toCall': (x, e, name, o) => wrapper(parserFuncs.parseWaitForPropertyFalse, x, e, name, o), + }, { 'name': 'wait-for-size', 'func': checkAssertSize,