| <!doctype html> |
| <title>Tests find-a-range-from-a-text-directive algorithm</title> |
| <meta charset=utf-8> |
| <link rel="help" href="https://wicg.github.io/scroll-to-text-fragment/#find-a-range-from-a-text-directive"> |
| <meta name="timeout" content="long"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="/resources/testdriver.js"></script> |
| <script src="/resources/testdriver-vendor.js"></script> |
| <script src="/common/utils.js"></script> |
| <script src="stash.js"></script> |
| <!-- |
| This test suite performs scroll to text navigations to |
| find-range-from-text-directive-target.html and then checks the results, which are |
| communicated back from the target page via the WPT Stash server (see stash.py). |
| This structure is necessary because scroll to text security restrictions |
| specifically restrict the navigator from being able to observe the result of |
| the navigation, e.g. the target page cannot have a window opener. |
| --> |
| <script> |
| // This test suite specifically exercises the "find a range from a text |
| // directive" algorithm in the spec. |
| |
| let test_cases = [ |
| { |
| fragment: '#:~:text=jumped', |
| expect_to_scroll: true, |
| description: 'Basic smoke test - full word match' |
| }, |
| { |
| // Step 2.2.1 |
| fragment: '#:~:text=u-,mped', |
| expect_to_scroll: false, |
| description: 'Prefix must start on a word boundary' |
| }, |
| { |
| // Step 2.2.1 |
| fragment: '#:~:text=ju-,mped', |
| expect_to_scroll: true, |
| description: 'Prefix need not end on a word boundary' |
| }, |
| { |
| // Step 2.2.2 |
| fragment: '#:~:text=null-,The%20quick', |
| expect_to_scroll: false, |
| description: 'Prefix doesn\'t exist' |
| }, |
| { |
| // Step 2.2.3 |
| fragment: '#:~:text=foo%20foo-,bar', |
| expect_to_scroll: true, |
| description: 'Multiple overlapping prefixes' |
| }, |
| { |
| // Step 2.2.3 |
| fragment: '#:~:text=a%20a-,b', |
| expect_to_scroll: true, |
| description: 'Multiple overlapping one letter prefixes' |
| }, |
| { |
| // Step 2.2.4 |
| fragment: '#:~:text=quick%20brown-,brown%20fox', |
| expect_to_scroll: false, |
| description: 'Prefix overlaps match text' |
| }, |
| { |
| // Step 2.2.4 |
| fragment: '#:~:text=quick%20brown-,fox', |
| expect_to_scroll: true, |
| description: 'Match text after prefix' |
| }, |
| { |
| // Step 2.2.5 |
| fragment: '#:~:text=Lorem-,Ipsum', |
| expect_to_scroll: true, |
| description: 'Search invisible content between prefix and match' |
| }, |
| { |
| // Step 2.2.6 |
| fragment: '#:~:text=end%20of%20the%20document-,test', |
| expect_to_scroll: false, |
| description: 'Prefix appears at end of document' |
| }, |
| { |
| // Step 2.2.8 |
| fragment: '#:~:text=fox-,jum,over', |
| expect_to_scroll: false, |
| description: '|end| forces |start| to end on word boundary' |
| }, |
| { |
| // Step 2.2.8 |
| fragment: '#:~:text=fox-,jum', |
| expect_to_scroll: false, |
| description: 'no |end| or suffix forces |start| to end on word boundary' |
| }, |
| { |
| // Step 2.2.8 |
| fragment: '#:~:text=fox-,jum,-ped', |
| expect_to_scroll: true, |
| description: 'suffix means |start| need not end on word boundary' |
| }, |
| { |
| // Step 2.2.9 |
| fragment: '#:~:text=jum-,ped', |
| expect_to_scroll: true, |
| description: '|start| doesn\'t need to start on word boundary' |
| }, |
| { |
| // Step 2.2.10 |
| fragment: '#:~:text=jumped-,null', |
| expect_to_scroll: false, |
| description: 'prefix with non-existent exact match' |
| }, |
| { |
| // Step 2.2.10 |
| fragment: '#:~:text=jumped-,null,lazy', |
| expect_to_scroll: false, |
| description: 'prefix with non-existent range match' |
| }, |
| { |
| // Step 2.2.11 |
| fragment: '#:~:text=brown-,jumped', |
| expect_to_scroll: false, |
| description: 'match doesn\'t immediately follow prefix' |
| }, |
| { |
| // Step 2.2.11 |
| fragment: '#:~:text=foo-,bar', |
| expect_to_scroll: true, |
| description: 'match doesn\'t immediately follow first prefix instance' |
| }, |
| { |
| // Step 2.3.1 |
| fragment: '#:~:text=jum,over', |
| expect_to_scroll: false, |
| description: 'no-prefix; |end| forces |start| to end on word boundary' |
| }, |
| { |
| // Step 2.3.1 |
| fragment: '#:~:text=jum', |
| expect_to_scroll: false, |
| description: 'no-prefix; no |end| or suffix forces |start| to end on word boundary' |
| }, |
| { |
| // Step 2.3.1 |
| fragment: '#:~:text=jum,-ped', |
| expect_to_scroll: true, |
| description: 'no-prefix; suffix means |start| need not end on word boundary' |
| }, |
| { |
| // Step 2.3.2 |
| fragment: '#:~:text=umped', |
| expect_to_scroll: false, |
| description: '|start| must start on a word boundary' |
| }, |
| { |
| // Step 2.3.3 |
| fragment: '#:~:text=null', |
| expect_to_scroll: false, |
| description: 'non-existent exact match' |
| }, |
| { |
| // Step 2.3.3 |
| fragment: '#:~:text=null,lazy', |
| expect_to_scroll: false, |
| description: 'non-existent range match' |
| }, |
| { |
| // Step 2.3.4 |
| fragment: '#:~:text=b%20b,-c', |
| expect_to_scroll: true, |
| description: 'overlapping exact matches with suffix' |
| }, |
| { |
| // Step 2.3.4 |
| fragment: '#:~:text=foo%20foo,-bar', |
| expect_to_scroll: true, |
| description: 'overlapping one letter exact matches with suffix' |
| }, |
| { |
| // Step 2.4.1 |
| fragment: '#:~:text=brown,fox', |
| expect_to_scroll: true, |
| description: 'matching range search' |
| }, |
| { |
| // Step 2.4.1 |
| fragment: '#:~:text=brown,quick', |
| expect_to_scroll: false, |
| description: 'inverted range search' |
| }, |
| { |
| // Step 2.4.2 |
| fragment: '#:~:text=quick,bro', |
| expect_to_scroll: false, |
| description: 'no suffix forces |end| to be end bounded' |
| }, |
| { |
| // Step 2.4.2 |
| fragment: '#:~:text=quick,bro,-wn', |
| expect_to_scroll: true, |
| description: 'suffix means |end| need not be end bounded' |
| }, |
| { |
| // Step 2.4.3 |
| fragment: '#:~:text=quick,ro,-wn', |
| expect_to_scroll: false, |
| description: '|end| must be start bounded' |
| }, |
| { |
| // Step 2.4.3 |
| fragment: '#:~:text=bro,wn', |
| expect_to_scroll: false, |
| description: '|end| must be start bounded even if full range is word bounded' |
| }, |
| { |
| // Step 2.4.4 |
| fragment: '#:~:text=quick,null', |
| expect_to_scroll: false, |
| description: 'non-existent |end|' |
| }, |
| { |
| // Step 2.4.5 |
| fragment: '#:~:text=quick,jumped,-fox', |
| expect_to_scroll: false, |
| description: 'Range with preceeding suffix' |
| }, |
| { |
| // Step 2.6 |
| fragment: '#:~:text=The-,quick,brown', |
| expect_to_scroll: true, |
| description: 'Match with no suffix' |
| }, |
| { |
| // Step 2.7 |
| fragment: '#:~:text=The-,quick,fox,-brown', |
| expect_to_scroll: false, |
| description: 'Suffix comes before |end|' |
| }, |
| { |
| // Step 2.8 |
| fragment: '#:~:text=Lorem-,Ipsum,Whitespace,-Dipsum', |
| expect_to_scroll: true, |
| description: 'Search invisible content between |end| and suffix' |
| }, |
| { |
| // Step 2.9 |
| fragment: '#:~:text=quick,-bro', |
| expect_to_scroll: false, |
| description: 'Suffix must be end bounded' |
| }, |
| { |
| // Step 2.9 |
| fragment: '#:~:text=qu,-ick', |
| expect_to_scroll: true, |
| description: 'Suffix need not be start bounded' |
| }, |
| { |
| // Step 2.10 |
| fragment: '#:~:text=quick,-null', |
| expect_to_scroll: false, |
| description: 'Non-existent suffix' |
| }, |
| { |
| // Step 2.11 |
| fragment: '#:~:text=quick,-fox', |
| expect_to_scroll: false, |
| description: 'Content appears between match and suffix' |
| } |
| ]; |
| |
| for (const test_case of test_cases) { |
| promise_test(t => new Promise((resolve, reject) => { |
| let key = token(); |
| |
| test_driver.bless('Open a URL with a text fragment directive', () => { |
| window.open(`find-range-from-text-directive-target.html?key=${key}${test_case.fragment}`, '_blank', 'noopener'); |
| }); |
| |
| fetchResults(key, resolve, reject); |
| }).then(data => { |
| const expectation_string = test_case.expect_to_scroll ? 'to scroll' : 'not to scroll'; |
| assert_equals(data.didScroll, test_case.expect_to_scroll, |
| `Expected ${expectation_string}`); |
| }), `${test_case.description}.`); |
| } |
| </script> |