| import pytest |
| from webdriver.bidi.modules.script import ContextTarget, ScriptEvaluateResultException |
| |
| from ... import any_int, any_string, recursive_compare |
| from .. import any_stack_trace |
| |
| |
| @pytest.mark.asyncio |
| async def test_invalid_script(bidi_session, top_context): |
| with pytest.raises(ScriptEvaluateResultException) as exception: |
| await bidi_session.script.evaluate( |
| expression="))) !!@@## some invalid JS script (((", |
| target=ContextTarget(top_context["context"]), |
| await_promise=True, |
| ) |
| recursive_compare( |
| { |
| "realm": any_string, |
| "exceptionDetails": { |
| "columnNumber": any_int, |
| "exception": {"type": "error"}, |
| "lineNumber": any_int, |
| "stackTrace": any_stack_trace, |
| "text": any_string, |
| }, |
| }, |
| exception.value.result, |
| ) |
| |
| |
| @pytest.mark.asyncio |
| @pytest.mark.parametrize("await_promise", [True, False]) |
| @pytest.mark.parametrize( |
| "expression, expected", |
| [ |
| ("undefined", {"type": "undefined"}), |
| ("null", {"type": "null"}), |
| ("'foobar'", {"type": "string", "value": "foobar"}), |
| ("'2'", {"type": "string", "value": "2"}), |
| ("Number.NaN", {"type": "number", "value": "NaN"}), |
| ("-0", {"type": "number", "value": "-0"}), |
| ("Infinity", {"type": "number", "value": "Infinity"}), |
| ("-Infinity", {"type": "number", "value": "-Infinity"}), |
| ("3", {"type": "number", "value": 3}), |
| ("1.4", {"type": "number", "value": 1.4}), |
| ("true", {"type": "boolean", "value": True}), |
| ("false", {"type": "boolean", "value": False}), |
| ("42n", {"type": "bigint", "value": "42"}), |
| ("(Symbol('foo'))", {"type": "symbol", },), |
| ( |
| "[1, 'foo', true, new RegExp(/foo/g), [1]]", |
| { |
| "type": "array", |
| "value": [ |
| {"type": "number", "value": 1}, |
| {"type": "string", "value": "foo"}, |
| {"type": "boolean", "value": True}, |
| { |
| "type": "regexp", |
| "value": { |
| "pattern": "foo", |
| "flags": "g", |
| }, |
| }, |
| {"type": "array"}, |
| ], |
| }, |
| ), |
| ( |
| "({'foo': {'bar': 'baz'}, 'qux': 'quux'})", |
| { |
| "type": "object", |
| "value": [ |
| ["foo", {"type": "object"}], |
| ["qux", {"type": "string", "value": "quux"}], |
| ], |
| }, |
| ), |
| ("(()=>{})", {"type": "function", },), |
| ("(function(){})", {"type": "function", },), |
| ("(async ()=>{})", {"type": "function", },), |
| ("(async function(){})", {"type": "function", },), |
| ( |
| "new RegExp(/foo/g)", |
| { |
| "type": "regexp", |
| "value": { |
| "pattern": "foo", |
| "flags": "g", |
| }, |
| }, |
| ), |
| ( |
| "new Date(1654004849000)", |
| { |
| "type": "date", |
| "value": "2022-05-31T13:47:29.000Z", |
| }, |
| ), |
| ( |
| "new Map([[1, 2], ['foo', 'bar'], [true, false], ['baz', [1]]])", |
| { |
| "type": "map", |
| "value": [ |
| [ |
| {"type": "number", "value": 1}, |
| {"type": "number", "value": 2}, |
| ], |
| ["foo", {"type": "string", "value": "bar"}], |
| [ |
| {"type": "boolean", "value": True}, |
| {"type": "boolean", "value": False}, |
| ], |
| ["baz", {"type": "array"}], |
| ], |
| }, |
| ), |
| ( |
| "new Set([1, 'foo', true, [1], new Map([[1,2]])])", |
| { |
| "type": "set", |
| "value": [ |
| {"type": "number", "value": 1}, |
| {"type": "string", "value": "foo"}, |
| {"type": "boolean", "value": True}, |
| {"type": "array"}, |
| {"type": "map"}, |
| ], |
| }, |
| ), |
| ("new WeakMap()", {"type": "weakmap", },), |
| ("new WeakSet()", {"type": "weakset", },), |
| ("new Error('SOME_ERROR_TEXT')", {"type": "error"},), |
| ("([1, 2][Symbol.iterator]())", { |
| "type": "iterator", |
| }), |
| ("new Proxy({}, {})", { |
| "type": "proxy" |
| }), |
| # generator |
| ("(function*() { yield 'a'; })", { |
| "type": "generator" |
| }), |
| ("Promise.resolve()", {"type": "promise", },), |
| ("new Int32Array()", {"type": "typedarray", },), |
| ("new ArrayBuffer()", {"type": "arraybuffer", },), |
| ( |
| "document.createElement('div')", |
| { |
| "type": "node", |
| 'value': { |
| 'attributes': {}, |
| 'childNodeCount': 0, |
| 'localName': 'div', |
| 'namespaceURI': 'http://www.w3.org/1999/xhtml', |
| 'nodeType': 1, |
| } |
| }, |
| ), |
| ("window", {"type": "window", },), |
| ], |
| ) |
| @pytest.mark.asyncio |
| async def test_exception_details(bidi_session, top_context, await_promise, expression, expected): |
| if await_promise: |
| expression = f"Promise.reject({expression})" |
| else: |
| expression = f"throw {expression}" |
| |
| with pytest.raises(ScriptEvaluateResultException) as exception: |
| await bidi_session.script.evaluate( |
| expression=expression, |
| target=ContextTarget(top_context["context"]), |
| await_promise=await_promise, |
| ) |
| |
| recursive_compare( |
| { |
| "realm": any_string, |
| "exceptionDetails": { |
| "columnNumber": any_int, |
| "exception": expected, |
| "lineNumber": any_int, |
| "stackTrace": any_stack_trace, |
| "text": any_string, |
| }, |
| }, |
| exception.value.result, |
| ) |
| |
| |
| @pytest.mark.asyncio |
| @pytest.mark.parametrize("chained", [True, False]) |
| async def test_rejected_promise(bidi_session, top_context, chained): |
| if chained: |
| expression = "Promise.reject('error').then(() => { })" |
| else: |
| expression = "Promise.reject('error')" |
| |
| with pytest.raises(ScriptEvaluateResultException) as exception: |
| await bidi_session.script.evaluate( |
| expression=expression, |
| await_promise=True, |
| target=ContextTarget(top_context["context"]), |
| ) |
| |
| recursive_compare( |
| { |
| "realm": any_string, |
| "exceptionDetails": { |
| "columnNumber": any_int, |
| "exception": {"type": "string", "value": "error"}, |
| "lineNumber": any_int, |
| "stackTrace": any_stack_trace, |
| "text": any_string, |
| }, |
| }, |
| exception.value.result, |
| ) |