11cb0ef41Sopenharmony_ci// The results of this test are all over the map due to browsers behaving very differently for
21cb0ef41Sopenharmony_ci// javascript: URLs.
31cb0ef41Sopenharmony_ci//
41cb0ef41Sopenharmony_ci// Chromium is pretty close execution-wise, but it parses javascript: URLs incorrectly.
51cb0ef41Sopenharmony_ci// Gecko navigates to non-string return values of the result of executing a javascript: URL.
61cb0ef41Sopenharmony_ci// WebKit executes javascript: URLs too early and has a harness error due to URL parsing.
71cb0ef41Sopenharmony_ci//
81cb0ef41Sopenharmony_ci// The expectations below should match the HTML and URL standards.
91cb0ef41Sopenharmony_ci[
101cb0ef41Sopenharmony_ci  {
111cb0ef41Sopenharmony_ci    "description": "javascript: URL that fails to parse due to invalid host",
121cb0ef41Sopenharmony_ci    "input": "javascript://test:test/%0aglobalThis.shouldNotExistA=1",
131cb0ef41Sopenharmony_ci    "property": "shouldNotExistA",
141cb0ef41Sopenharmony_ci    "expected": undefined
151cb0ef41Sopenharmony_ci  },
161cb0ef41Sopenharmony_ci  {
171cb0ef41Sopenharmony_ci    "description": "javascript: URL that fails to parse due to invalid host and has a U+0009 in scheme",
181cb0ef41Sopenharmony_ci    "input": "java\x09script://test:test/%0aglobalThis.shouldNotExistB=1",
191cb0ef41Sopenharmony_ci    "property": "shouldNotExistB",
201cb0ef41Sopenharmony_ci    "expected": undefined
211cb0ef41Sopenharmony_ci  },
221cb0ef41Sopenharmony_ci  {
231cb0ef41Sopenharmony_ci    "description": "javascript: URL without an opaque path",
241cb0ef41Sopenharmony_ci    "input": "javascript://host/1%0a//../0/;globalThis.shouldBeOne=1;/%0aglobalThis.shouldBeOne=2;/..///",
251cb0ef41Sopenharmony_ci    "property": "shouldBeOne",
261cb0ef41Sopenharmony_ci    "expected": 1
271cb0ef41Sopenharmony_ci  },
281cb0ef41Sopenharmony_ci  {
291cb0ef41Sopenharmony_ci    "description": "javascript: URL containing a JavaScript string split over path and query",
301cb0ef41Sopenharmony_ci    // Use ";undefined" to avoid returning a string.
311cb0ef41Sopenharmony_ci    "input": "javascript:globalThis.shouldBeAStringA = \"https://whatsoever.com/?a=b&c=5&x=y\";undefined",
321cb0ef41Sopenharmony_ci    "property": "shouldBeAStringA",
331cb0ef41Sopenharmony_ci    "expected": "https://whatsoever.com/?a=b&c=5&x=y"
341cb0ef41Sopenharmony_ci  },
351cb0ef41Sopenharmony_ci  {
361cb0ef41Sopenharmony_ci    "description": "javascript: URL containing a JavaScript string split over path and query and has a U+000A in scheme",
371cb0ef41Sopenharmony_ci    // Use ";undefined" to avoid returning a string.
381cb0ef41Sopenharmony_ci    "input": "java\x0Ascript:globalThis.shouldBeAStringB = \"https://whatsoever.com/?a=b&c=5&x=y\";undefined",
391cb0ef41Sopenharmony_ci    "property": "shouldBeAStringB",
401cb0ef41Sopenharmony_ci    "expected": "https://whatsoever.com/?a=b&c=5&x=y"
411cb0ef41Sopenharmony_ci  }
421cb0ef41Sopenharmony_ci].forEach(({ description, input, property, expected }) => {
431cb0ef41Sopenharmony_ci  // Use promise_test so the tests run in sequence. Needed for globalThis.verify below.
441cb0ef41Sopenharmony_ci  promise_test(t => {
451cb0ef41Sopenharmony_ci    const anchor = document.body.appendChild(document.createElement("a"));
461cb0ef41Sopenharmony_ci    t.add_cleanup(() => anchor.remove());
471cb0ef41Sopenharmony_ci    anchor.href = input;
481cb0ef41Sopenharmony_ci    assert_equals(globalThis[property], undefined, "Property is undefined before the click");
491cb0ef41Sopenharmony_ci    anchor.click();
501cb0ef41Sopenharmony_ci    assert_equals(globalThis[property], undefined, "Property is undefined immediately after the click");
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci    // Since we cannot reliably queue a task to run after the task queued as a result of the click()
531cb0ef41Sopenharmony_ci    // above, we do another click() with a new URL.
541cb0ef41Sopenharmony_ci    return new Promise(resolve => {
551cb0ef41Sopenharmony_ci      globalThis.verify = t.step_func(() => {
561cb0ef41Sopenharmony_ci        assert_equals(globalThis[property], expected, `Property is ${expected} once the navigation happened`);
571cb0ef41Sopenharmony_ci        resolve();
581cb0ef41Sopenharmony_ci      });
591cb0ef41Sopenharmony_ci      anchor.href = "javascript:globalThis.verify()";
601cb0ef41Sopenharmony_ci      anchor.click();
611cb0ef41Sopenharmony_ci    });
621cb0ef41Sopenharmony_ci  }, description);
631cb0ef41Sopenharmony_ci});
64