Pop-up dictionary browser extension for language learning. Successor to Yomichan. (PERSONAL FORK)

HTML test updates (#398)

* Rename y-test to test-case

* Rename y-description to test-description

* Remove extension name

* Update placeholder favicon

* Refactor scripts

* Make element types more consistent

* More updates

* Rename

* Simplify file URLs

* Rename file

* Add descriptions

* Rename

* Rename

* Rename

authored by

toasted-nutbread and committed by
GitHub
0a0994ca 3c226215

+632 -553
+12 -4
.eslintrc.json
··· 661 661 }, 662 662 { 663 663 "files": [ 664 - "test/data/html/*.js" 664 + "test/data/html/**/*.js" 665 665 ], 666 666 "parserOptions": { 667 667 "sourceType": "script" ··· 670 670 "browser": true, 671 671 "node": false, 672 672 "webextensions": false 673 - }, 674 - "rules": { 675 - "no-implicit-globals": "off" 673 + } 674 + }, 675 + { 676 + "files": [ 677 + "test/data/html/**/*.js" 678 + ], 679 + "excludedFiles": [ 680 + "test/data/html/js/html-test-utilities.js" 681 + ], 682 + "globals": { 683 + "HtmlTestUtilities": "readonly" 676 684 } 677 685 }, 678 686 {
+184
test/data/html/js/html-test-utilities.js
··· 1 + /* 2 + * Copyright (C) 2023 Yomitan Authors 3 + * Copyright (C) 2021-2022 Yomichan Authors 4 + * 5 + * This program is free software: you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License as published by 7 + * the Free Software Foundation, either version 3 of the License, or 8 + * (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program. If not, see <https://www.gnu.org/licenses/>. 17 + */ 18 + 19 + class HtmlTestUtilities { 20 + /** 21 + * @param {Element} element 22 + */ 23 + static requestFullscreen(element) { 24 + if (element.requestFullscreen) { 25 + element.requestFullscreen(); 26 + // @ts-expect-error - Browser compatibility 27 + } else if (element.mozRequestFullScreen) { 28 + // @ts-expect-error - Browser compatibility 29 + element.mozRequestFullScreen(); 30 + // @ts-expect-error - Browser compatibility 31 + } else if (element.webkitRequestFullscreen) { 32 + // @ts-expect-error - Browser compatibility 33 + element.webkitRequestFullscreen(); 34 + // @ts-expect-error - Browser compatibility 35 + } else if (element.msRequestFullscreen) { 36 + // @ts-expect-error - Browser compatibility 37 + element.msRequestFullscreen(); 38 + } 39 + } 40 + 41 + /** */ 42 + static exitFullscreen() { 43 + if (document.exitFullscreen) { 44 + document.exitFullscreen(); 45 + // @ts-expect-error - Browser compatibility 46 + } else if (document.mozCancelFullScreen) { 47 + // @ts-expect-error - Browser compatibility 48 + document.mozCancelFullScreen(); 49 + // @ts-expect-error - Browser compatibility 50 + } else if (document.webkitExitFullscreen) { 51 + // @ts-expect-error - Browser compatibility 52 + document.webkitExitFullscreen(); 53 + // @ts-expect-error - Browser compatibility 54 + } else if (document.msExitFullscreen) { 55 + // @ts-expect-error - Browser compatibility 56 + document.msExitFullscreen(); 57 + } 58 + } 59 + 60 + /** 61 + * @returns {?Element} 62 + */ 63 + static getFullscreenElement() { 64 + return ( 65 + document.fullscreenElement || 66 + // @ts-expect-error - Browser compatibility 67 + document.msFullscreenElement || 68 + // @ts-expect-error - Browser compatibility 69 + document.mozFullScreenElement || 70 + // @ts-expect-error - Browser compatibility 71 + document.webkitFullscreenElement || 72 + null 73 + ); 74 + } 75 + 76 + /** 77 + * @param {Element} element 78 + */ 79 + static toggleFullscreen(element) { 80 + if (this.getFullscreenElement()) { 81 + this.exitFullscreen(); 82 + } else { 83 + this.requestFullscreen(element); 84 + } 85 + } 86 + 87 + /** 88 + * @param {string} string 89 + * @returns {Uint8Array} 90 + */ 91 + static stringToTypedArray(string) { 92 + const array = new Uint8Array(string.length); 93 + for (let i = 0; i < string.length; ++i) { 94 + array[i] = string.charCodeAt(i); 95 + } 96 + return array; 97 + } 98 + 99 + /** 100 + * @param {string} dataUrl 101 + * @returns {{content: string, type: string}} 102 + * @throws {Error} 103 + */ 104 + static dataUrlToContent(dataUrl) { 105 + const match = /^data:([^;]*);(base64,)?([\w\W]*)$/.exec(dataUrl); 106 + if (match === null) { throw new Error('Invalid input'); } 107 + const [, type, isBase64, data] = match; 108 + const content = ( 109 + isBase64 ? 110 + new TextDecoder().decode(this.stringToTypedArray(atob(data))) : 111 + data 112 + ); 113 + return {content, type}; 114 + } 115 + 116 + /** 117 + * @param {string} dataUrl 118 + * @returns {Blob} 119 + */ 120 + static dataUrlToBlob(dataUrl) { 121 + const {content, type} = this.dataUrlToContent(dataUrl); 122 + return new Blob([content], {type}); 123 + } 124 + 125 + /** 126 + * @param {?Element} element 127 + * @returns {string} 128 + * @throws {Error} 129 + */ 130 + static getIframeSrc(element) { 131 + if (!(element instanceof HTMLIFrameElement)) { 132 + throw new Error('Element is not an iframe'); 133 + } 134 + return element.src; 135 + } 136 + 137 + /** 138 + * @param {Element|DocumentFragment} container 139 + * @param {?Element} [fullscreenElement] 140 + */ 141 + static setupTest(container, fullscreenElement = null) { 142 + const fullscreenLink = container.querySelector('.fullscreen-link'); 143 + if (fullscreenLink !== null) { 144 + if (fullscreenElement === null) { 145 + fullscreenElement = container.querySelector('.fullscreen-element'); 146 + } 147 + fullscreenLink.addEventListener('click', (e) => { 148 + if (fullscreenElement === null) { return; } 149 + this.toggleFullscreen(fullscreenElement); 150 + e.preventDefault(); 151 + return false; 152 + }, false); 153 + } 154 + 155 + const template = container.querySelector('template'); 156 + const templateContentContainer = container.querySelector('.template-content-container'); 157 + if (template !== null && templateContentContainer !== null) { 158 + const mode = (container instanceof HTMLElement ? container.dataset.shadowMode : void 0); 159 + const shadow = templateContentContainer.attachShadow({ 160 + mode: (mode === 'open' || mode === 'closed' ? mode : 'open') 161 + }); 162 + 163 + const containerStyles = document.querySelector('#container-styles'); 164 + if (containerStyles !== null) { 165 + shadow.appendChild(containerStyles.cloneNode(true)); 166 + } 167 + 168 + const content = document.importNode(template.content, true); 169 + this.setupTest(content); 170 + shadow.appendChild(content); 171 + } 172 + } 173 + 174 + /** 175 + * @param {() => void} main 176 + */ 177 + static runMain(main) { 178 + if (document.readyState === 'loading') { 179 + document.addEventListener('DOMContentLoaded', () => { main(); }); 180 + } else { 181 + main(); 182 + } 183 + } 184 + }
+63
test/data/html/js/performance-frames.js
··· 1 + /* 2 + * Copyright (C) 2023 Yomitan Authors 3 + * 4 + * This program is free software: you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation, either version 3 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 + */ 17 + 18 + HtmlTestUtilities.runMain(() => { 19 + let totalCount = 0; 20 + const container = document.querySelector('#container'); 21 + const counter = document.querySelector('#counter'); 22 + 23 + /** 24 + * @param {number} count 25 + * @param {Event} event 26 + */ 27 + function addElements(count, event) { 28 + event.preventDefault(); 29 + 30 + if (container !== null) { 31 + for (let i = 0; i < count; ++i) { 32 + const element = document.createElement('div'); 33 + element.textContent = 'ありがとう'; 34 + container.appendChild(element); 35 + } 36 + } 37 + 38 + totalCount += count; 39 + if (counter !== null) { 40 + counter.textContent = `${totalCount}`; 41 + } 42 + } 43 + 44 + for (const element of document.querySelectorAll('.add-elements')) { 45 + if (!(element instanceof HTMLElement)) { continue; } 46 + const {count} = element.dataset; 47 + if (typeof count !== 'string') { continue; } 48 + const countValue = Number.parseInt(count, 10); 49 + if (!Number.isFinite(countValue)) { continue; } 50 + element.addEventListener('click', addElements.bind(null, countValue)); 51 + } 52 + 53 + const shadowIframeContainer = document.querySelector('#shadow-iframe-container-open'); 54 + if (shadowIframeContainer !== null) { 55 + const shadow = shadowIframeContainer.attachShadow({mode: 'open'}); 56 + const templateElement = document.querySelector('#shadow-iframe-container-open-content-template'); 57 + if (templateElement instanceof HTMLTemplateElement) { 58 + const template = templateElement.content; 59 + const content = document.importNode(template, true); 60 + shadow.appendChild(content); 61 + } 62 + } 63 + });
+21
test/data/html/js/popup-tests-frame1.js
··· 1 + /* 2 + * Copyright (C) 2023 Yomitan Authors 3 + * 4 + * This program is free software: you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation, either version 3 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 + */ 17 + 18 + HtmlTestUtilities.runMain(() => { 19 + const {body} = document; 20 + HtmlTestUtilities.setupTest(body, body); 21 + });
+33
test/data/html/js/popup-tests.js
··· 1 + /* 2 + * Copyright (C) 2023 Yomitan Authors 3 + * 4 + * This program is free software: you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation, either version 3 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 + */ 17 + 18 + HtmlTestUtilities.runMain(() => { 19 + for (const element of document.querySelectorAll('test-case')) { 20 + HtmlTestUtilities.setupTest(element); 21 + } 22 + 23 + const iframeWithDataUrl = document.querySelector('#iframe-with-data-url'); 24 + const src = HtmlTestUtilities.getIframeSrc(iframeWithDataUrl); 25 + const iframeWithBlobUrl = document.querySelector('#iframe-with-blob-url'); 26 + if (iframeWithBlobUrl instanceof HTMLIFrameElement) { 27 + iframeWithBlobUrl.src = URL.createObjectURL(HtmlTestUtilities.dataUrlToBlob(src)); 28 + } 29 + for (const iframeWithSrcdoc of document.querySelectorAll('.iframe-with-srcdoc')) { 30 + if (!(iframeWithSrcdoc instanceof HTMLIFrameElement)) { continue; } 31 + iframeWithSrcdoc.srcdoc = HtmlTestUtilities.dataUrlToContent(src).content; 32 + } 33 + });
+26
test/data/html/performance-frame1.html
··· 1 + <!DOCTYPE html> 2 + <html> 3 + <head> 4 + <meta charset="UTF-8"> 5 + <meta name="viewport" content="width=device-width,initial-scale=1"> 6 + <title>Performance Tests</title> 7 + <link rel="stylesheet" href="test-stylesheet.css"> 8 + <script src="js/html-test-utilities.js"></script> 9 + <script src="js/performance-frames.js"></script> 10 + </head> 11 + <body><div class="content"> 12 + 13 + <test-description>Add elements</test-description> 14 + 15 + <div> 16 + <a href="#" class="add-elements" data-count="1000">1000</a> 17 + <a href="#" class="add-elements" data-count="10000">10000</a> 18 + <a href="#" class="add-elements" data-count="100000">100000</a> 19 + <a href="#" class="add-elements" data-count="1000000">1000000</a> 20 + </div> 21 + 22 + <div id="counter"></div> 23 + <div id="container"></div> 24 + 25 + </div></body> 26 + </html>
+33
test/data/html/performance-frame2.html
··· 1 + <!DOCTYPE html> 2 + <html> 3 + <head> 4 + <meta charset="UTF-8"> 5 + <meta name="viewport" content="width=device-width,initial-scale=1"> 6 + <title>Performance Tests</title> 7 + <link rel="stylesheet" href="test-stylesheet.css"> 8 + <script src="js/html-test-utilities.js"></script> 9 + <script src="js/performance-frames.js"></script> 10 + </head> 11 + <body><div class="content"> 12 + 13 + <test-description>&lt;iframe&gt; element inside of an open shadow DOM.</test-description> 14 + 15 + <div id="shadow-iframe-container-open"></div> 16 + <template id="shadow-iframe-container-open-content-template"> 17 + <iframe src="popup-tests-frame1.html" allowfullscreen="true" style="width: 100%; height: 50px; border: 1px solid #d8d8d8;"></iframe> 18 + </template> 19 + 20 + <test-description>Add elements</test-description> 21 + 22 + <div> 23 + <a href="#" class="add-elements" data-count="1000">1000</a> 24 + <a href="#" class="add-elements" data-count="10000">10000</a> 25 + <a href="#" class="add-elements" data-count="100000">100000</a> 26 + <a href="#" class="add-elements" data-count="1000000">1000000</a> 27 + </div> 28 + 29 + <div id="counter"></div> 30 + <div id="container"></div> 31 + 32 + </div></body> 33 + </html>
+27
test/data/html/performance.html
··· 1 + <!DOCTYPE html> 2 + <html> 3 + <head> 4 + <meta charset="UTF-8"> 5 + <meta name="viewport" content="width=device-width,initial-scale=1"> 6 + <title>Performance Tests</title> 7 + <link rel="icon" type="image/gif" href="data:image/gif;base64,R0lGODdhAQABAIABAAAAAP///ywAAAAAAQABAAACAkQBADs="> 8 + <link rel="stylesheet" href="test-stylesheet.css"> 9 + </head> 10 + <body> 11 + 12 + <h1>Performance Tests</h1> 13 + 14 + <test-description>Testing performance with artificially demanding cases in a real browser</test-description> 15 + 16 + <test-case> 17 + <test-description>&lt;iframe&gt; element.</test-description> 18 + <iframe src="performance-frame1.html" allowfullscreen="true" style="width: 100%; height: 200px; border: 1px solid #d8d8d8;"></iframe> 19 + </test-case> 20 + 21 + <test-case> 22 + <test-description>&lt;iframe&gt; element containing an &lt;iframe&gt; element inside of an open shadow DOM.</test-description> 23 + <iframe src="performance-frame2.html" allowfullscreen="true" style="width: 100%; height: 200px; border: 1px solid #d8d8d8;"></iframe> 24 + </test-case> 25 + 26 + </body> 27 + </html>
+45 -60
test/data/html/test-document1.html test/data/html/document-util.html
··· 1 1 <!DOCTYPE html> 2 2 <html> 3 - <head> 4 - <meta charset="UTF-8"> 5 - <meta name="viewport" content="width=device-width,initial-scale=1"> 6 - <title>Yomitan Tests</title> 7 - <link rel="icon" type="image/gif" href="data:image/gif;base64,R0lGODlhEAAQAKEBAAAAAP///////////yH5BAEKAAIALAAAAAAQABAAAAImFI6Zpt0B4YkS0TCpq07xbmEgcGVRUpLaI46ZG7ppalY0jDCwUAAAOw=="> 8 - <link rel="stylesheet" href="test-stylesheet.css"> 9 - </head> 3 + <head> 4 + <meta charset="UTF-8"> 5 + <meta name="viewport" content="width=device-width,initial-scale=1"> 6 + <title>DocumentUtil Tests</title> 7 + <link rel="icon" type="image/gif" href="data:image/gif;base64,R0lGODdhAQABAIABAAAAAP///ywAAAAAAQABAAACAkQBADs="> 8 + <link rel="stylesheet" href="test-stylesheet.css"> 9 + </head> 10 10 <body> 11 11 12 - <h1>Yomitan Tests</h1> 12 + <h1>DocumentUtil Tests</h1> 13 + 14 + <test-description>Automated test cases for DocumentUtil.</test-description> 13 15 14 - <div 15 - class="test" 16 + <test-case 16 17 data-test-type="scan" 17 18 data-element-from-point-selector="span" 18 19 data-caret-range-from-point-selector="span" ··· 25 26 data-sentence="真白「心配してくださって、ありがとございます」" 26 27 > 27 28 <span>真白「心配してくださって、ありがとございます」</span> 28 - </div> 29 + </test-case> 29 30 30 - <div 31 - class="test" 31 + <test-case 32 32 data-test-type="scan" 33 33 data-element-from-point-selector="span" 34 34 data-caret-range-from-point-selector="span" ··· 41 41 data-sentence="心配してくださって、ありがとございます" 42 42 > 43 43 <span>真白「心配してくださって、ありがとございます」</span> 44 - </div> 44 + </test-case> 45 45 46 - <div 47 - class="test" 46 + <test-case 48 47 data-test-type="scan" 49 48 data-element-from-point-selector="span" 50 49 data-caret-range-from-point-selector="span" ··· 57 56 data-sentence="心配して「くださって」、ありがと「ございます」" 58 57 > 59 58 <span>真白「心配して「くださって」、ありがと「ございます」」</span> 60 - </div> 59 + </test-case> 61 60 62 - <div 63 - class="test" 61 + <test-case 64 62 data-test-type="scan" 65 63 data-element-from-point-selector="span" 66 64 data-caret-range-from-point-selector="span" ··· 73 71 data-sentence="ありがとございます。" 74 72 > 75 73 <span>ありがとございます。ありがとございます。</span> 76 - </div> 74 + </test-case> 77 75 78 - <div 79 - class="test" 76 + <test-case 80 77 data-test-type="scan" 81 78 data-element-from-point-selector="span" 82 79 data-caret-range-from-point-selector="span" ··· 89 86 data-sentence="ありがとございます。" 90 87 > 91 88 <span>ありがとございます。ありがとございます。</span> 92 - </div> 89 + </test-case> 93 90 94 - <div 95 - class="test" 91 + <test-case 96 92 data-test-type="scan" 97 93 data-element-from-point-selector="span" 98 94 data-caret-range-from-point-selector="span" ··· 105 101 data-sentence="ありがとございます。!?" 106 102 > 107 103 <span>ありがとございます。!?ありがとございます。!?</span> 108 - </div> 104 + </test-case> 109 105 110 - <div 111 - class="test" 106 + <test-case 112 107 data-test-type="scan" 113 108 data-element-from-point-selector="span" 114 109 data-caret-range-from-point-selector="span" ··· 121 116 data-sentence="ありがとございます!!!" 122 117 > 123 118 <span>ありがとございます!!!ありがとございます!!!</span> 124 - </div> 119 + </test-case> 125 120 126 - <div 127 - class="test" 121 + <test-case 128 122 data-test-type="scan" 129 123 data-element-from-point-selector="input" 130 124 data-caret-range-from-point-selector="input" ··· 138 132 data-has-imposter="true" 139 133 > 140 134 <input type="text" value="真白「心配してくださって、ありがとございます」" style="width: 100%; box-sizing: border-box; font-family: inherit; font-size: inherit; border: 1px solid #d8d8d8; padding: 0.2em;"> 141 - </div> 135 + </test-case> 142 136 143 - <div 144 - class="test" 137 + <test-case 145 138 data-test-type="scan" 146 139 data-element-from-point-selector="textarea" 147 140 data-caret-range-from-point-selector="textarea" ··· 155 148 data-has-imposter="true" 156 149 > 157 150 <textarea style="width: 100%; height: 3em; box-sizing: border-box; font-family: inherit; font-size: inherit; border: 1px solid #d8d8d8; padding: 0.2em;">真白「心配してくださって、ありがとございます」</textarea> 158 - </div> 151 + </test-case> 159 152 160 - <div 161 - class="test" 153 + <test-case 162 154 data-test-type="scan" 163 155 data-element-from-point-selector="button" 164 156 data-caret-range-from-point-selector="button" ··· 171 163 data-sentence="よみたん" 172 164 > 173 165 <button type="button" style="width: 100%; box-sizing: border-box; font-family: inherit; font-size: inherit; border: 1px solid #d8d8d8; background-color: #f0f0f0; padding: 0.2em;">よみたん</button> 174 - </div> 166 + </test-case> 175 167 176 - <div 177 - class="test" 168 + <test-case 178 169 data-test-type="scan" 179 170 data-element-from-point-selector="img" 180 171 data-caret-range-from-point-selector="img" ··· 186 177 data-sentence-scan-extent="100" 187 178 data-sentence="よみたん" 188 179 > 189 - <img src="data:image/gif;base64,R0lGODdhBwAHAIABAAAAAP///ywAAAAABwAHAAACDIRvEaC32FpCbEkKCgA7" alt="よみたん" title="よみたん" style="width: 70px; height: 70px; image-rendering: crisp-edges; image-rendering: pixelated; display: block;"> 190 - </div> 180 + <img src="data:image/gif;base64,R0lGODdhAQABAIABAAAAAP///ywAAAAAAQABAAACAkQBADs=" alt="よみたん" title="よみたん" style="width: 70px; height: 70px; image-rendering: crisp-edges; image-rendering: pixelated; display: block;"> 181 + </test-case> 191 182 192 - <div 193 - class="test" 183 + <test-case 194 184 data-test-type="scan" 195 185 data-element-from-point-selector="span:nth-of-type(3)" 196 186 data-caret-range-from-point-selector="span:nth-of-type(3)" ··· 208 198 <span>ありがとございます3</span> 209 199 <span>ありがとございます4</span> 210 200 <span>ありがとございます5</span> 211 - </div> 201 + </test-case> 212 202 213 - <div 214 - class="test" 203 + <test-case 215 204 data-test-type="scan" 216 205 data-element-from-point-selector="span:nth-of-type(3)" 217 206 data-caret-range-from-point-selector="span:nth-of-type(3)" ··· 229 218 <span>ありがとございます3</span> 230 219 <span>ありがとございます4</span> 231 220 <span>ありがとございます5</span> 232 - </div> 221 + </test-case> 233 222 234 - <div 235 - class="test" 223 + <test-case 236 224 data-test-type="text-source-range-seek" 237 225 data-seek-node-selector="span:nth-of-type(1)" 238 226 data-seek-node-is-text="true" ··· 267 255 らりるれろ 268 256 わゐ&#x3000;ゑを 269 257 </span><span>trailing content</span> 270 - </div> 258 + </test-case> 271 259 272 - <div 273 - class="test" 260 + <test-case 274 261 data-test-type="text-source-range-seek" 275 262 data-seek-node-selector="span:nth-of-type(1)" 276 263 data-seek-node-is-text="true" ··· 305 292 らりるれろ 306 293 わゐ&#x3000;ゑを 307 294 </span><span>trailing content</span> 308 - </div> 295 + </test-case> 309 296 310 - <div 311 - class="test" 297 + <test-case 312 298 data-test-type="text-source-range-seek" 313 299 data-seek-node-selector="span:nth-of-type(1)" 314 300 data-seek-node-is-text="true" ··· 343 329 らりるれろ 344 330 わゐ&#x3000;ゑを 345 331 </span><span>trailing content</span> 346 - </div> 332 + </test-case> 347 333 348 - <div 349 - class="test" 334 + <test-case 350 335 data-test-type="text-source-range-seek" 351 336 data-seek-node-selector="span:nth-of-type(2)" 352 337 data-seek-node-is-text="true" ··· 381 366 らりるれろ 382 367 わゐ&#x3000;ゑを 383 368 </span><span>trailing content</span> 384 - </div> 369 + </test-case> 385 370 386 371 </body> 387 372 </html>
+9 -9
test/data/html/test-document2-frame1.html test/data/html/popup-tests-frame1.html
··· 1 1 <!DOCTYPE html> 2 2 <html> 3 - <head> 4 - <meta charset="UTF-8"> 5 - <meta name="viewport" content="width=device-width,initial-scale=1"> 6 - <title>Yomitan Tests</title> 7 - <script src="test-document2-script.js"></script> 8 - <style> 3 + <head> 4 + <meta charset="UTF-8"> 5 + <meta name="viewport" content="width=device-width,initial-scale=1"> 6 + <title>Frame 1</title> 7 + <script src="js/html-test-utilities.js"></script> 8 + <script src="js/popup-tests-frame1.js"></script> 9 + <style> 9 10 body { 10 11 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 11 12 font-size: 14px; ··· 26 27 padding: 0.5em; 27 28 background-color: #f8f8f8; 28 29 } 29 - </style> 30 - </head> 30 + </style> 31 + </head> 31 32 <body><div class="content"> 32 33 <div> 33 34 ありがとう 34 35 </div> 35 36 <div> 36 37 <a href="#" class="fullscreen-link">Toggle fullscreen</a> 37 - <script>setup(document.body, document.body);</script> 38 38 </div> 39 39 </div></body> 40 40 </html>
test/data/html/test-document2-frame2.svg test/data/html/popup-tests-frame2.svg
-121
test/data/html/test-document2-script.js
··· 1 - /* 2 - * Copyright (C) 2023 Yomitan Authors 3 - * Copyright (C) 2021-2022 Yomichan Authors 4 - * 5 - * This program is free software: you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License as published by 7 - * the Free Software Foundation, either version 3 of the License, or 8 - * (at your option) any later version. 9 - * 10 - * This program is distributed in the hope that it will be useful, 11 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 - * GNU General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program. If not, see <https://www.gnu.org/licenses/>. 17 - */ 18 - 19 - /** 20 - * @param {Element} element 21 - */ 22 - function requestFullscreen(element) { 23 - if (element.requestFullscreen) { 24 - element.requestFullscreen(); 25 - // @ts-expect-error - Browser compatibility 26 - } else if (element.mozRequestFullScreen) { 27 - // @ts-expect-error - Browser compatibility 28 - element.mozRequestFullScreen(); 29 - // @ts-expect-error - Browser compatibility 30 - } else if (element.webkitRequestFullscreen) { 31 - // @ts-expect-error - Browser compatibility 32 - element.webkitRequestFullscreen(); 33 - // @ts-expect-error - Browser compatibility 34 - } else if (element.msRequestFullscreen) { 35 - // @ts-expect-error - Browser compatibility 36 - element.msRequestFullscreen(); 37 - } 38 - } 39 - 40 - /** */ 41 - function exitFullscreen() { 42 - if (document.exitFullscreen) { 43 - document.exitFullscreen(); 44 - // @ts-expect-error - Browser compatibility 45 - } else if (document.mozCancelFullScreen) { 46 - // @ts-expect-error - Browser compatibility 47 - document.mozCancelFullScreen(); 48 - // @ts-expect-error - Browser compatibility 49 - } else if (document.webkitExitFullscreen) { 50 - // @ts-expect-error - Browser compatibility 51 - document.webkitExitFullscreen(); 52 - // @ts-expect-error - Browser compatibility 53 - } else if (document.msExitFullscreen) { 54 - // @ts-expect-error - Browser compatibility 55 - document.msExitFullscreen(); 56 - } 57 - } 58 - 59 - /** 60 - * @returns {?Element} 61 - */ 62 - function getFullscreenElement() { 63 - return ( 64 - document.fullscreenElement || 65 - // @ts-expect-error - Browser compatibility 66 - document.msFullscreenElement || 67 - // @ts-expect-error - Browser compatibility 68 - document.mozFullScreenElement || 69 - // @ts-expect-error - Browser compatibility 70 - document.webkitFullscreenElement || 71 - null 72 - ); 73 - } 74 - 75 - /** 76 - * @param {Element} element 77 - */ 78 - function toggleFullscreen(element) { 79 - if (getFullscreenElement()) { 80 - exitFullscreen(); 81 - } else { 82 - requestFullscreen(element); 83 - } 84 - } 85 - 86 - /** 87 - * @param {HTMLElement|DocumentFragment} container 88 - * @param {?Element} [fullscreenElement] 89 - */ 90 - function setup(container, fullscreenElement = null) { 91 - const fullscreenLink = container.querySelector('.fullscreen-link'); 92 - if (fullscreenLink !== null) { 93 - if (fullscreenElement === null) { 94 - fullscreenElement = container.querySelector('.fullscreen-element'); 95 - } 96 - fullscreenLink.addEventListener('click', (e) => { 97 - if (fullscreenElement === null) { return; } 98 - toggleFullscreen(fullscreenElement); 99 - e.preventDefault(); 100 - return false; 101 - }, false); 102 - } 103 - 104 - const template = container.querySelector('template'); 105 - const templateContentContainer = container.querySelector('.template-content-container'); 106 - if (template !== null && templateContentContainer !== null) { 107 - const mode = (container instanceof HTMLElement ? container.dataset.shadowMode : void 0); 108 - const shadow = templateContentContainer.attachShadow({ 109 - mode: (mode === 'open' || mode === 'closed' ? mode : 'open') 110 - }); 111 - 112 - const containerStyles = document.querySelector('#container-styles'); 113 - if (containerStyles !== null) { 114 - shadow.appendChild(containerStyles.cloneNode(true)); 115 - } 116 - 117 - const content = document.importNode(template.content, true); 118 - setup(content); 119 - shadow.appendChild(content); 120 - } 121 - }
+87 -129
test/data/html/test-document2.html test/data/html/popup-tests.html
··· 1 1 <!DOCTYPE html> 2 2 <html> 3 - 4 3 <head> 5 4 <meta charset="UTF-8"> 6 5 <meta name="viewport" content="width=device-width,initial-scale=1"> 7 - <title>Yomitan Manual Tests</title> 8 - <link rel="icon" type="image/gif" 9 - href="data:image/gif;base64,R0lGODlhEAAQAKEBAAAAAP///////////yH5BAEKAAIALAAAAAAQABAAAAImFI6Zpt0B4YkS0TCpq07xbmEgcGVRUpLaI46ZG7ppalY0jDCwUAAAOw=="> 6 + <title>Popup Tests</title> 7 + <link rel="icon" type="image/gif" href="data:image/gif;base64,R0lGODdhAQABAIABAAAAAP///ywAAAAAAQABAAACAkQBADs="> 10 8 <link rel="stylesheet" href="test-stylesheet.css"> 11 - <script src="test-document2-script.js"></script> 12 - </head> 13 - <style id="container-styles"> 14 - .container { 15 - width: 100%; 16 - height: 200px; 17 - border: 1px solid #d8d8d8; 18 - position: relative; 19 - box-sizing: border-box; 20 - } 21 - 22 - .container-inner { 23 - background-color: #f8f8f8; 24 - padding: 0.5em; 25 - position: absolute; 26 - left: 0; 27 - top: 0; 28 - bottom: 0; 29 - right: 0; 30 - } 31 - 32 - .danger { 33 - color: #c83c28; 34 - } 9 + <script src="js/html-test-utilities.js"></script> 10 + <script src="js/popup-tests.js"></script> 11 + <style id="container-styles"> 12 + .container { 13 + width: 100%; 14 + height: 200px; 15 + border: 1px solid #d8d8d8; 16 + position: relative; 17 + box-sizing: border-box; 18 + } 35 19 36 - </style> 20 + .container-inner { 21 + background-color: #f8f8f8; 22 + padding: 0.5em; 23 + position: absolute; 24 + left: 0; 25 + top: 0; 26 + bottom: 0; 27 + right: 0; 28 + } 37 29 30 + .danger { 31 + color: #c83c28; 32 + } 33 + </style> 34 + </head> 38 35 <body> 36 + <h1>Popup Tests</h1> 39 37 40 - <h1>Yomitan Manual Tests</h1> 41 - <y-description>Manual tests involving fullscreen elements, &lt;iframe&gt;s, and shadow DOMs.</y-description> 38 + <test-description> 39 + Tests involving popup functionality in different contextsts, such as fullscreen elements, &lt;iframe&gt; elements, and shadow DOMs. 40 + </test-description> 42 41 43 - <y-test> 44 - <y-description>Standard content.</y-description> 42 + <test-case> 43 + <test-description>Standard content.</test-description> 45 44 <div class="fullscreen-element container hovertarget"> 46 45 <div class="container-inner"> 47 46 <div> ··· 52 51 </div> 53 52 </div> 54 53 </div> 55 - </y-test> 54 + </test-case> 56 55 57 - <y-test data-shadow-mode="open"> 58 - <y-description>Content inside of an open shadow DOM.</y-description> 56 + <test-case data-shadow-mode="open"> 57 + <test-description>Content inside of an open shadow DOM.</test-description> 59 58 <div class="template-content-container hovertarget"></div> 60 59 <template> 61 60 <link rel="stylesheet" href="test-stylesheet.css"> ··· 70 69 </div> 71 70 </div> 72 71 </template> 73 - </y-test> 72 + </test-case> 74 73 75 - <y-test data-shadow-mode="closed"> 76 - <y-description>Content inside of a closed shadow DOM.</y-description> 74 + <test-case data-shadow-mode="closed"> 75 + <test-description>Content inside of a closed shadow DOM.</test-description> 77 76 <div class="template-content-container hovertarget"></div> 78 77 <template> 79 78 <link rel="stylesheet" href="test-stylesheet.css"> ··· 88 87 </div> 89 88 </div> 90 89 </template> 91 - </y-test> 90 + </test-case> 92 91 93 - <y-test> 94 - <y-description>&lt;iframe&gt; element.</y-description> 95 - <iframe src="test-document2-frame1.html" allowfullscreen="true" class="container hovertarget"></iframe> 96 - </y-test> 92 + <test-case> 93 + <test-description>&lt;iframe&gt; element.</test-description> 94 + <iframe src="popup-tests-frame1.html" allowfullscreen="true" class="container hovertarget"></iframe> 95 + </test-case> 97 96 98 - <y-test data-shadow-mode="open"> 99 - <y-description>&lt;iframe&gt; element inside of an open shadow DOM.</y-description> 97 + <test-case data-shadow-mode="open"> 98 + <test-description>&lt;iframe&gt; element inside of an open shadow DOM.</test-description> 100 99 <div class="template-content-container hovertarget"></div> 101 100 <template> 102 - <iframe src="test-document2-frame1.html" allowfullscreen="true" class="container"></iframe> 101 + <iframe src="popup-tests-frame1.html" allowfullscreen="true" class="container"></iframe> 103 102 </template> 104 - </y-test> 103 + </test-case> 105 104 106 - <y-test data-shadow-mode="closed"> 107 - <y-description>&lt;iframe&gt; element inside of a closed shadow DOM.</y-description> 105 + <test-case data-shadow-mode="closed"> 106 + <test-description>&lt;iframe&gt; element inside of a closed shadow DOM.</test-description> 108 107 <div class="template-content-container hovertarget"></div> 109 108 <template> 110 - <iframe src="test-document2-frame1.html" allowfullscreen="true" class="container"></iframe> 109 + <iframe src="popup-tests-frame1.html" allowfullscreen="true" class="container"></iframe> 111 110 </template> 112 - </y-test> 111 + </test-case> 113 112 114 - <y-test> 115 - <y-description>&lt;iframe&gt; element with data URL.</y-description> 113 + <test-case> 114 + <test-description>&lt;iframe&gt; element with data URL.</test-description> 116 115 <iframe id="iframe-with-data-url" 117 116 src="data:text/html;base64,PCFET0NUWVBFIGh0bWw+DQo8aHRtbD4NCiAgICA8aGVhZD4NCiAgICAgICAgPG1ldGEgY2hhcnNldD0iVVRGLTgiPg0KICAgICAgICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLGluaXRpYWwtc2NhbGU9MSI+DQogICAgICAgIDx0aXRsZT5Zb21pY2hhbiBUZXN0czwvdGl0bGU+DQogICAgICAgIDxzY3JpcHQ+DQogZnVuY3Rpb24gcmVxdWVzdEZ1bGxzY3JlZW4oZWxlbWVudCkgew0KICAgIGlmIChlbGVtZW50LnJlcXVlc3RGdWxsc2NyZWVuKSB7DQogICAgICAgIGVsZW1lbnQucmVxdWVzdEZ1bGxzY3JlZW4oKTsNCiAgICB9IGVsc2UgaWYgKGVsZW1lbnQubW96UmVxdWVzdEZ1bGxTY3JlZW4pIHsNCiAgICAgICAgZWxlbWVudC5tb3pSZXF1ZXN0RnVsbFNjcmVlbigpOw0KICAgIH0gZWxzZSBpZiAoZWxlbWVudC53ZWJraXRSZXF1ZXN0RnVsbHNjcmVlbikgew0KICAgICAgICBlbGVtZW50LndlYmtpdFJlcXVlc3RGdWxsc2NyZWVuKCk7DQogICAgfSBlbHNlIGlmIChlbGVtZW50Lm1zUmVxdWVzdEZ1bGxzY3JlZW4pIHsNCiAgICAgICAgZWxlbWVudC5tc1JlcXVlc3RGdWxsc2NyZWVuKCk7DQogICAgfQ0KfQ0KDQpmdW5jdGlvbiBleGl0RnVsbHNjcmVlbigpIHsNCiAgICBpZiAoZG9jdW1lbnQuZXhpdEZ1bGxzY3JlZW4pIHsNCiAgICAgICAgZG9jdW1lbnQuZXhpdEZ1bGxzY3JlZW4oKTsNCiAgICB9IGVsc2UgaWYgKGRvY3VtZW50Lm1vekNhbmNlbEZ1bGxTY3JlZW4pIHsNCiAgICAgICAgZG9jdW1lbnQubW96Q2FuY2VsRnVsbFNjcmVlbigpOw0KICAgIH0gZWxzZSBpZiAoZG9jdW1lbnQud2Via2l0RXhpdEZ1bGxzY3JlZW4pIHsNCiAgICAgICAgZG9jdW1lbnQud2Via2l0RXhpdEZ1bGxzY3JlZW4oKTsNCiAgICB9IGVsc2UgaWYgKGRvY3VtZW50Lm1zRXhpdEZ1bGxzY3JlZW4pIHsNCiAgICAgICAgZG9jdW1lbnQubXNFeGl0RnVsbHNjcmVlbigpOw0KICAgIH0NCn0NCg0KZnVuY3Rpb24gZ2V0RnVsbHNjcmVlbkVsZW1lbnQoKSB7DQogICAgcmV0dXJuICgNCiAgICAgICAgZG9jdW1lbnQuZnVsbHNjcmVlbkVsZW1lbnQgfHwNCiAgICAgICAgZG9jdW1lbnQubXNGdWxsc2NyZWVuRWxlbWVudCB8fA0KICAgICAgICBkb2N1bWVudC5tb3pGdWxsU2NyZWVuRWxlbWVudCB8fA0KICAgICAgICBkb2N1bWVudC53ZWJraXRGdWxsc2NyZWVuRWxlbWVudCB8fA0KICAgICAgICBudWxsDQogICAgKTsNCn0NCg0KZnVuY3Rpb24gdG9nZ2xlRnVsbHNjcmVlbihlbGVtZW50KSB7DQogICAgaWYgKGdldEZ1bGxzY3JlZW5FbGVtZW50KCkpIHsNCiAgICAgICAgZXhpdEZ1bGxzY3JlZW4oKTsNCiAgICB9IGVsc2Ugew0KICAgICAgICByZXF1ZXN0RnVsbHNjcmVlbihlbGVtZW50KTsNCiAgICB9DQp9DQoNCmZ1bmN0aW9uIHNldHVwKGNvbnRhaW5lciwgZnVsbHNjcmVlbkVsZW1lbnQ9bnVsbCkgew0KICAgIGNvbnN0IGZ1bGxzY3JlZW5MaW5rID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJy5mdWxsc2NyZWVuLWxpbmsnKTsNCiAgICBpZiAoZnVsbHNjcmVlbkxpbmsgIT09IG51bGwpIHsNCiAgICAgICAgaWYgKGZ1bGxzY3JlZW5FbGVtZW50ID09PSBudWxsKSB7DQogICAgICAgICAgICBmdWxsc2NyZWVuRWxlbWVudCA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCcuZnVsbHNjcmVlbi1lbGVtZW50Jyk7DQogICAgICAgIH0NCiAgICAgICAgZnVsbHNjcmVlbkxpbmsuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZSkgPT4gew0KICAgICAgICAgICAgdG9nZ2xlRnVsbHNjcmVlbihmdWxsc2NyZWVuRWxlbWVudCk7DQogICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7DQogICAgICAgICAgICByZXR1cm4gZmFsc2U7DQogICAgICAgIH0sIGZhbHNlKTsNCiAgICB9DQoNCiAgICBjb25zdCB0ZW1wbGF0ZSA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCd0ZW1wbGF0ZScpOw0KICAgIGNvbnN0IHRlbXBsYXRlQ29udGVudENvbnRhaW5lciA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCcudGVtcGxhdGUtY29udGVudC1jb250YWluZXInKTsNCiAgICBpZiAodGVtcGxhdGUgIT09IG51bGwgJiYgdGVtcGxhdGVDb250ZW50Q29udGFpbmVyICE9PSBudWxsKSB7DQogICAgICAgIGNvbnN0IG1vZGUgPSBjb250YWluZXIuZGF0YXNldC5zaGFkb3dNb2RlOw0KICAgICAgICBjb25zdCBzaGFkb3cgPSB0ZW1wbGF0ZUNvbnRlbnRDb250YWluZXIuYXR0YWNoU2hhZG93KHttb2RlfSk7DQoNCiAgICAgICAgY29uc3QgY29udGFpbmVyU3R5bGVzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2NvbnRhaW5lci1zdHlsZXMnKTsNCiAgICAgICAgc2hhZG93LmFwcGVuZENoaWxkKGNvbnRhaW5lclN0eWxlcy5jbG9uZU5vZGUodHJ1ZSkpOw0KDQogICAgICAgIGNvbnN0IGNvbnRlbnQgPSBkb2N1bWVudC5pbXBvcnROb2RlKHRlbXBsYXRlLmNvbnRlbnQsIHRydWUpOw0KICAgICAgICBzZXR1cChjb250ZW50KTsNCiAgICAgICAgc2hhZG93LmFwcGVuZENoaWxkKGNvbnRlbnQpOw0KICAgIH0NCn0NCiAgICAgICAgPC9zY3JpcHQ+DQogICAgICAgIDxzdHlsZT4NCmJvZHkgew0KICAgIGZvbnQtZmFtaWx5OiAiSGVsdmV0aWNhIE5ldWUiLCBIZWx2ZXRpY2EsIEFyaWFsLCBzYW5zLXNlcmlmOw0KICAgIGZvbnQtc2l6ZTogMTRweDsNCiAgICBwYWRkaW5nOiAwOw0KICAgIG1hcmdpbjogMDsNCiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjhmOGY4Ow0KfQ0KYSwgYTp2aXNpdGVkIHsNCiAgICBjb2xvcjogIzEwODBjMDsNCiAgICB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTsNCn0NCi5jb250ZW50IHsNCiAgICBwb3NpdGlvbjogYWJzb2x1dGU7DQogICAgbGVmdDogMDsNCiAgICB0b3A6IDA7DQogICAgcmlnaHQ6IDA7DQogICAgYm90dG9tOiAwOw0KICAgIHBhZGRpbmc6IDAuNWVtOw0KICAgIGJhY2tncm91bmQtY29sb3I6ICNmOGY4Zjg7DQp9DQogICAgICAgIDwvc3R5bGU+DQogICAgPC9oZWFkPg0KPGJvZHk+PGRpdiBjbGFzcz0iY29udGVudCI+DQo8ZGl2Pg0KICAgIOOBguOCiuOBjOOBqOOBhg0KPC9kaXY+DQo8ZGl2Pg0KICAgIDxhIGhyZWY9IiMiIGNsYXNzPSJmdWxsc2NyZWVuLWxpbmsiPlRvZ2dsZSBmdWxsc2NyZWVuPC9hPg0KICAgIDxzY3JpcHQ+c2V0dXAoZG9jdW1lbnQuYm9keSwgZG9jdW1lbnQuYm9keSk7PC9zY3JpcHQ+DQo8L2Rpdj4NCjwvZGl2PjwvYm9keT4NCjwvaHRtbD4=" 118 117 allowfullscreen="true" class="container hovertarget"></iframe> 119 - </y-test> 118 + </test-case> 120 119 121 - <y-test> 122 - <y-description>&lt;iframe&gt; element with blob URL.</y-description> 120 + <test-case> 121 + <test-description>&lt;iframe&gt; element with blob URL.</test-description> 123 122 <iframe id="iframe-with-blob-url" allowfullscreen="true" class="container hovertarget"></iframe> 124 - </y-test> 123 + </test-case> 125 124 126 - <y-test> 127 - <y-description>&lt;iframe&gt; element with srcdoc.</y-description> 125 + <test-case> 126 + <test-description>&lt;iframe&gt; element with srcdoc.</test-description> 128 127 <iframe allowfullscreen="true" class="iframe-with-srcdoc container hovertarget"></iframe> 129 - </y-test> 128 + </test-case> 130 129 131 - <y-test> 132 - <y-description>&lt;iframe&gt; element with srcdoc and 133 - <code>sandbox="allow-same-origin allow-scripts"</code>.</y-description> 130 + <test-case> 131 + <test-description>&lt;iframe&gt; element with srcdoc and 132 + <code>sandbox="allow-same-origin allow-scripts"</code>.</test-description> 134 133 <iframe allowfullscreen="true" class="iframe-with-srcdoc container hovertarget" 135 134 sandbox="allow-same-origin allow-scripts"></iframe> 136 - </y-test> 135 + </test-case> 137 136 138 - <y-test> 139 - <y-description> 137 + <test-case> 138 + <test-description> 140 139 &lt;iframe&gt; element with srcdoc and <code>sandbox="allow-scripts"</code>.<br> 141 140 <span class="danger">This element is expected to not work.</span> 142 - </y-description> 141 + </test-description> 143 142 <iframe allowfullscreen="true" class="iframe-with-srcdoc container hovertarget" 144 143 sandbox="allow-scripts"></iframe> 145 - </y-test> 144 + </test-case> 146 145 147 - <y-test> 148 - <y-description>SVG &lt;img&gt;.</y-description> 149 - <img src="test-document2-frame2.svg" class="container hovertarget" alt=""> 150 - </y-test> 146 + <test-case> 147 + <test-description>SVG &lt;img&gt;.</test-description> 148 + <img src="popup-tests-frame2.svg" class="container hovertarget" alt=""> 149 + </test-case> 151 150 152 - <y-test> 153 - <y-description>SVG &lt;object&gt;.</y-description> 154 - <object data="test-document2-frame2.svg" type="image/svg+xml" class="container hovertarget"></object> 155 - </y-test> 151 + <test-case> 152 + <test-description>SVG &lt;object&gt;.</test-description> 153 + <object data="popup-tests-frame2.svg" type="image/svg+xml" class="container hovertarget"></object> 154 + </test-case> 156 155 157 - <y-test> 158 - <y-description>SVG &lt;embed&gt;.</y-description> 159 - <embed type="image/svg+xml" src="test-document2-frame2.svg" class="container hovertarget"> 160 - </y-test> 156 + <test-case> 157 + <test-description>SVG &lt;embed&gt;.</test-description> 158 + <embed type="image/svg+xml" src="popup-tests-frame2.svg" class="container hovertarget"> 159 + </test-case> 161 160 162 - <y-test> 163 - <y-description>SVG &lt;iframe&gt;.</y-description> 164 - <iframe src="test-document2-frame2.svg" allowfullscreen="true" class="container hovertarget"></iframe> 165 - </y-test> 161 + <test-case> 162 + <test-description>SVG &lt;iframe&gt;.</test-description> 163 + <iframe src="popup-tests-frame2.svg" allowfullscreen="true" class="container hovertarget"></iframe> 164 + </test-case> 166 165 167 - <y-test> 168 - <y-description>SVG &lt;svg&gt;.</y-description> 166 + <test-case> 167 + <test-description>SVG &lt;svg&gt;.</test-description> 169 168 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="container hovertarget" 170 169 style="background-color: #f8f8f8;" focusable="false"> 171 170 <text x="7" y="12" style=" ··· 176 175 ありがとう 177 176 </text> 178 177 </svg> 179 - </y-test> 180 - 181 - 182 - <script> 183 - (() => { 184 - function stringToTypedArray(string) { 185 - const array = new Uint8Array(string.length); 186 - for (let i = 0; i < string.length; ++i) { 187 - array[i] = string.charCodeAt(i); 188 - } 189 - return array; 190 - } 191 - 192 - function dataUrlToContent(dataUrl) { 193 - const [, type, isBase64, data] = /^data:([^;]*);(base64,)?([\w\W]*)$/.exec(dataUrl); 194 - const content = ( 195 - isBase64 ? 196 - new TextDecoder().decode(stringToTypedArray(atob(data))) : 197 - data 198 - ); 199 - return { content, type }; 200 - } 201 - 202 - function dataUrlToBlob(dataUrl) { 203 - const { content, type } = dataUrlToContent(dataUrl); 204 - return new Blob([content], { type }); 205 - } 206 - 207 - for (const element of document.querySelectorAll('y-test')) { 208 - setup(element); 209 - } 210 - 211 - const iframeWithDataUrl = document.querySelector('#iframe-with-data-url'); 212 - const iframeWithBlobUrl = document.querySelector('#iframe-with-blob-url'); 213 - iframeWithBlobUrl.src = URL.createObjectURL(dataUrlToBlob(iframeWithDataUrl.src)); 214 - for (const iframeWithSrcdoc of document.querySelectorAll('.iframe-with-srcdoc')) { 215 - iframeWithSrcdoc.srcdoc = dataUrlToContent(iframeWithDataUrl.src).content; 216 - } 217 - })(); 218 - </script> 219 - 178 + </test-case> 220 179 </body> 221 - 222 180 </html>
-44
test/data/html/test-document3-frame1.html
··· 1 - <!DOCTYPE html> 2 - <html> 3 - <head> 4 - <meta charset="UTF-8"> 5 - <meta name="viewport" content="width=device-width,initial-scale=1"> 6 - <title>Yomitan Manual Performance Tests</title> 7 - <link rel="stylesheet" href="test-stylesheet.css"> 8 - </head> 9 - <body><div class="content"> 10 - 11 - <div class="description">Add elements</div> 12 - 13 - <div> 14 - <a href="#" id="add-elements-1000">1000</a> 15 - <a href="#" id="add-elements-10000">10000</a> 16 - <a href="#" id="add-elements-100000">100000</a> 17 - <a href="#" id="add-elements-1000000">1000000</a> 18 - <script> 19 - document.querySelector('#add-elements-1000').addEventListener('click', () => addElements(1000), false); 20 - document.querySelector('#add-elements-10000').addEventListener('click', () => addElements(10000), false); 21 - document.querySelector('#add-elements-100000').addEventListener('click', () => addElements(100000), false); 22 - document.querySelector('#add-elements-1000000').addEventListener('click', () => addElements(1000000), false); 23 - 24 - let counter = 0; 25 - 26 - function addElements(amount) { 27 - const container = document.querySelector('#container'); 28 - for (let i = 0; i < amount; i++) { 29 - const element = document.createElement('div'); 30 - element.textContent = 'ありがとう'; 31 - container.appendChild(element); 32 - } 33 - 34 - counter += amount; 35 - document.querySelector('#counter').textContent = counter; 36 - } 37 - </script> 38 - </div> 39 - 40 - <div id="counter"></div> 41 - <div id="container"></div> 42 - 43 - </div></body> 44 - </html>
-62
test/data/html/test-document3-frame2.html
··· 1 - <!DOCTYPE html> 2 - <html> 3 - <head> 4 - <meta charset="UTF-8"> 5 - <meta name="viewport" content="width=device-width,initial-scale=1"> 6 - <title>Yomitan Manual Performance Tests</title> 7 - <link rel="stylesheet" href="test-stylesheet.css"> 8 - </head> 9 - <body><div class="content"> 10 - 11 - <div class="description">&lt;iframe&gt; element inside of an open shadow DOM.</div> 12 - 13 - <div id="shadow-iframe-container-open"></div> 14 - <template id="shadow-iframe-container-open-content-template"> 15 - <iframe src="test-document2-frame1.html" allowfullscreen="true" style="width: 100%; height: 50px; border: 1px solid #d8d8d8;"></iframe> 16 - </template> 17 - <script> 18 - (() => { 19 - const shadowIframeContainer = document.querySelector('#shadow-iframe-container-open'); 20 - const shadow = shadowIframeContainer.attachShadow({mode: 'open'}); 21 - const template = document.querySelector('#shadow-iframe-container-open-content-template').content; 22 - const content = document.importNode(template, true); 23 - shadow.appendChild(content); 24 - })(); 25 - </script> 26 - 27 - <div class="description">Add elements</div> 28 - 29 - <div> 30 - <a href="#" id="add-elements-1000">1000</a> 31 - <a href="#" id="add-elements-10000">10000</a> 32 - <a href="#" id="add-elements-100000">100000</a> 33 - <a href="#" id="add-elements-1000000">1000000</a> 34 - </div> 35 - 36 - <div id="counter"></div> 37 - <div id="container"></div> 38 - <script> 39 - (() => { 40 - document.querySelector('#add-elements-1000').addEventListener('click', () => addElements(1000), false); 41 - document.querySelector('#add-elements-10000').addEventListener('click', () => addElements(10000), false); 42 - document.querySelector('#add-elements-100000').addEventListener('click', () => addElements(100000), false); 43 - document.querySelector('#add-elements-1000000').addEventListener('click', () => addElements(1000000), false); 44 - 45 - let counter = 0; 46 - 47 - function addElements(amount) { 48 - const container = document.querySelector('#container'); 49 - for (let i = 0; i < amount; i++) { 50 - const element = document.createElement('div'); 51 - element.textContent = 'ありがとう'; 52 - container.appendChild(element); 53 - } 54 - 55 - counter += amount; 56 - document.querySelector('#counter').textContent = counter; 57 - } 58 - })(); 59 - </script> 60 - 61 - </div></body> 62 - </html>
-26
test/data/html/test-document3.html
··· 1 - <!DOCTYPE html> 2 - <html> 3 - <head> 4 - <meta charset="UTF-8"> 5 - <meta name="viewport" content="width=device-width,initial-scale=1"> 6 - <title>Yomitan Manual Performance Tests</title> 7 - <link rel="icon" type="image/gif" href="data:image/gif;base64,R0lGODlhEAAQAKEBAAAAAP///////////yH5BAEKAAIALAAAAAAQABAAAAImFI6Zpt0B4YkS0TCpq07xbmEgcGVRUpLaI46ZG7ppalY0jDCwUAAAOw=="> 8 - <link rel="stylesheet" href="test-stylesheet.css"> 9 - </head> 10 - <body> 11 - 12 - <h1>Yomitan Manual Performance Tests</h1> 13 - <p class="description">Testing Yomitan performance with artificially demanding cases in a real browser</p> 14 - 15 - <div class="test"> 16 - <div class="description">&lt;iframe&gt; element.</div> 17 - <iframe src="test-document3-frame1.html" allowfullscreen="true" style="width: 100%; height: 200px; border: 1px solid #d8d8d8;"></iframe> 18 - </div> 19 - 20 - <div class="test"> 21 - <div class="description">&lt;iframe&gt; element containing an &lt;iframe&gt; element inside of an open shadow DOM.</div> 22 - <iframe src="test-document3-frame2.html" allowfullscreen="true" style="width: 100%; height: 200px; border: 1px solid #d8d8d8;"></iframe> 23 - </div> 24 - 25 - </body> 26 - </html>
+79 -77
test/data/html/test-dom-text-scanner.html test/data/html/dom-text-scanner.html
··· 1 1 <!DOCTYPE html> 2 2 <html> 3 - <head> 4 - <meta charset="UTF-8"> 5 - <meta name="viewport" content="width=device-width,initial-scale=1"> 6 - <title>Yomitan DOMTextScanner Tests</title> 7 - <link rel="icon" type="image/gif" href="data:image/gif;base64,R0lGODlhEAAQAKEBAAAAAP///////////yH5BAEKAAIALAAAAAAQABAAAAImFI6Zpt0B4YkS0TCpq07xbmEgcGVRUpLaI46ZG7ppalY0jDCwUAAAOw=="> 8 - <link rel="stylesheet" href="test-stylesheet.css"> 9 - </head> 3 + <head> 4 + <meta charset="UTF-8"> 5 + <meta name="viewport" content="width=device-width,initial-scale=1"> 6 + <title>DOMTextScanner Tests</title> 7 + <link rel="icon" type="image/gif" href="data:image/gif;base64,R0lGODdhAQABAIABAAAAAP///ywAAAAAAQABAAACAkQBADs="> 8 + <link rel="stylesheet" href="test-stylesheet.css"> 9 + </head> 10 10 <body> 11 11 12 - <h1>Yomitan DOMTextScanner Tests</h1> 12 + <h1>DOMTextScanner Tests</h1> 13 + 14 + <test-description>Automated test cases for DOMTextScanner.</test-description> 13 15 14 - <y-test 16 + <test-case 15 17 data-test-data='{ 16 18 "node": "div:nth-of-type(1)", 17 19 "offset": 0, ··· 23 25 } 24 26 }' 25 27 > 26 - <y-description>Layout newlines expected due to entering and exiting display:block nodes.</y-description> 28 + <test-description>Layout newlines expected due to entering and exiting display:block nodes.</test-description> 27 29 <div><div>小ぢん</div>まり1</div> 28 30 <div>小ぢん<div>まり2</div></div> 29 - </y-test> 31 + </test-case> 30 32 31 - <y-test 33 + <test-case 32 34 data-test-data='{ 33 35 "node": "div:nth-of-type(1)::text", 34 36 "offset": 0, ··· 40 42 } 41 43 }' 42 44 > 43 - <y-description>Layout newline expected due to sequential display:block elements.</y-description> 45 + <test-description>Layout newline expected due to sequential display:block elements.</test-description> 44 46 <div>小ぢんまり1</div><div>小ぢんまり2</div> 45 - </y-test> 47 + </test-case> 46 48 47 - <y-test 49 + <test-case 48 50 data-test-data='{ 49 51 "node": "div:nth-of-type(1)::text", 50 52 "offset": 0, ··· 56 58 } 57 59 }' 58 60 > 59 - <y-description>Layout newline expected due to sequential display:block elements separated by a newline.</y-description> 61 + <test-description>Layout newline expected due to sequential display:block elements separated by a newline.</test-description> 60 62 <div>小ぢんまり1</div> 61 63 <div>小ぢんまり2</div> 62 - </y-test> 64 + </test-case> 63 65 64 - <y-test 66 + <test-case 65 67 data-test-data='{ 66 68 "node": "span:nth-of-type(1)::text", 67 69 "offset": 0, ··· 73 75 } 74 76 }' 75 77 > 76 - <y-description>No newlines expected due to display:inline.</y-description> 78 + <test-description>No newlines expected due to display:inline.</test-description> 77 79 <span>小ぢんまり1</span><span>小ぢんまり2</span> 78 - </y-test> 80 + </test-case> 79 81 80 - <y-test 82 + <test-case 81 83 data-test-data='{ 82 84 "node": "span:nth-of-type(1)::text", 83 85 "offset": 0, ··· 89 91 } 90 92 }' 91 93 > 92 - <y-description>No newlines expected due to white-space:normal.</y-description> 94 + <test-description>No newlines expected due to white-space:normal.</test-description> 93 95 <span>小ぢんまり1</span> 94 96 <span>小ぢんまり2</span> 95 - </y-test> 97 + </test-case> 96 98 97 - <y-test 99 + <test-case 98 100 data-test-data='{ 99 101 "node": "span:nth-of-type(1)::text", 100 102 "offset": 0, ··· 106 108 } 107 109 }' 108 110 > 109 - <y-description>Newline expected due to white-space:pre.</y-description> 111 + <test-description>Newline expected due to white-space:pre.</test-description> 110 112 <pre> 111 113 <span>小ぢんまり1</span> 112 114 <span>小ぢんまり2</span> 113 115 </pre> 114 - </y-test> 116 + </test-case> 115 117 116 - <y-test 118 + <test-case 117 119 data-test-data='{ 118 120 "node": "span:nth-of-type(1)::text", 119 121 "offset": 0, ··· 125 127 } 126 128 }' 127 129 > 128 - <y-description>No newlines expected due to display:inline-block. Actual layout flow cannot be determined by DOM/CSS alone.</y-description> 130 + <test-description>No newlines expected due to display:inline-block. Actual layout flow cannot be determined by DOM/CSS alone.</test-description> 129 131 <span style="display: inline-block;">小ぢんまり1</span><span style="display: inline-block;">小ぢんまり2</span> 130 - </y-test> 132 + </test-case> 131 133 132 - <y-test 134 + <test-case 133 135 style="position: relative;" 134 136 data-test-data='{ 135 137 "node": "div:nth-of-type(1)::text", ··· 142 144 } 143 145 }' 144 146 > 145 - <y-description>Single newline expected due to display:block layout.</y-description> 147 + <test-description>Single newline expected due to display:block layout.</test-description> 146 148 <div>小ぢんまり1</div><div style="position: relative;">小ぢんまり2</div> 147 - </y-test> 149 + </test-case> 148 150 149 - <y-test 151 + <test-case 150 152 style="position: relative; overflow: hidden;" 151 153 data-test-data='{ 152 154 "node": "div:nth-of-type(1)::text", ··· 159 161 } 160 162 }' 161 163 > 162 - <y-description>Two newlines expected due to position:absolute causing a significant layout change.</y-description> 164 + <test-description>Two newlines expected due to position:absolute causing a significant layout change.</test-description> 163 165 <div>小ぢんまり1</div><div style="position: absolute;">小ぢんまり2</div> 164 - </y-test> 166 + </test-case> 165 167 166 - <y-test 168 + <test-case 167 169 style="position: relative; overflow: hidden;" 168 170 data-test-data='{ 169 171 "node": "div:nth-of-type(1)::text", ··· 176 178 } 177 179 }' 178 180 > 179 - <y-description>Two newlines expected due to position:fixed causing a significant layout change.</y-description> 181 + <test-description>Two newlines expected due to position:fixed causing a significant layout change.</test-description> 180 182 <div>小ぢんまり1</div><div style="position: fixed;">小ぢんまり2</div> 181 - </y-test> 183 + </test-case> 182 184 183 - <y-test 185 + <test-case 184 186 style="position: relative;" 185 187 data-test-data='{ 186 188 "node": "div:nth-of-type(1)::text", ··· 193 195 } 194 196 }' 195 197 > 196 - <y-description>Two newlines expected due to position:sticky being able to cause a significant layout change.</y-description> 198 + <test-description>Two newlines expected due to position:sticky being able to cause a significant layout change.</test-description> 197 199 <div>小ぢんまり1</div><div style="position: sticky;">小ぢんまり2</div> 198 - </y-test> 200 + </test-case> 199 201 200 - <y-test 202 + <test-case 201 203 data-test-data='{ 202 204 "node": "rt", 203 205 "offset": 0, ··· 209 211 } 210 212 }' 211 213 > 212 - <y-description>Scanning text starting in an &lt;rt&gt; element. Should start scanning at the start of the &lt;ruby&gt; tag instead.</y-description> 214 + <test-description>Scanning text starting in an &lt;rt&gt; element. Should start scanning at the start of the &lt;ruby&gt; tag instead.</test-description> 213 215 <div><ruby>小<rp>(</rp><rt>こ</rt><rp>)</rp></ruby>ぢんまり1</div> 214 - </y-test> 216 + </test-case> 215 217 216 - <y-test 218 + <test-case 217 219 data-test-data='{ 218 220 "node": "div", 219 221 "offset": 0, ··· 225 227 } 226 228 }' 227 229 > 228 - <y-description>Skip &lt;script&gt; content.</y-description> 230 + <test-description>Skip &lt;script&gt; content.</test-description> 229 231 <div>小ぢん<script>/*comment*/</script>まり1</div> 230 - </y-test> 232 + </test-case> 231 233 232 - <y-test 234 + <test-case 233 235 data-test-data='{ 234 236 "node": "div", 235 237 "offset": 0, ··· 241 243 } 242 244 }' 243 245 > 244 - <y-description>Skip &lt;style&gt; content.</y-description> 246 + <test-description>Skip &lt;style&gt; content.</test-description> 245 247 <div>小ぢん<style>/*comment*/</style>まり1</div> 246 - </y-test> 248 + </test-case> 247 249 248 - <y-test 250 + <test-case 249 251 data-test-data='{ 250 252 "node": "div", 251 253 "offset": 0, ··· 257 259 } 258 260 }' 259 261 > 260 - <y-description>Skip &lt;textarea&gt; content.</y-description> 262 + <test-description>Skip &lt;textarea&gt; content.</test-description> 261 263 <div>小ぢん<textarea>textarea content</textarea>まり1</div> 262 - </y-test> 264 + </test-case> 263 265 264 - <y-test 266 + <test-case 265 267 data-test-data='{ 266 268 "node": "div", 267 269 "offset": 0, ··· 273 275 } 274 276 }' 275 277 > 276 - <y-description>Skip &lt;input&gt; content.</y-description> 278 + <test-description>Skip &lt;input&gt; content.</test-description> 277 279 <div>小ぢん<input value="content">まり1</div> 278 - </y-test> 280 + </test-case> 279 281 280 - <y-test 282 + <test-case 281 283 data-test-data='{ 282 284 "node": "div", 283 285 "offset": 0, ··· 289 291 } 290 292 }' 291 293 > 292 - <y-description>Skip &lt;button&gt; content.</y-description> 294 + <test-description>Skip &lt;button&gt; content.</test-description> 293 295 <div>小ぢん<button type="button">content</button>まり1</div> 294 - </y-test> 296 + </test-case> 295 297 296 - <y-test 298 + <test-case 297 299 data-test-data='{ 298 300 "node": "div", 299 301 "offset": 0, ··· 305 307 } 306 308 }' 307 309 > 308 - <y-description>Skip content with font-size:0.</y-description> 310 + <test-description>Skip content with font-size:0.</test-description> 309 311 <div>小ぢん<span style="font-size: 0;">content</span>まり1</div> 310 - </y-test> 312 + </test-case> 311 313 312 - <y-test 314 + <test-case 313 315 data-test-data='{ 314 316 "node": "div", 315 317 "offset": 0, ··· 321 323 } 322 324 }' 323 325 > 324 - <y-description>Skip content with opacity:0.</y-description> 326 + <test-description>Skip content with opacity:0.</test-description> 325 327 <div>小ぢん<span style="opacity: 0;">content</span>まり1</div> 326 - </y-test> 328 + </test-case> 327 329 328 - <y-test 330 + <test-case 329 331 data-test-data='{ 330 332 "node": "div", 331 333 "offset": 0, ··· 337 339 } 338 340 }' 339 341 > 340 - <y-description>Skip content with visibility:hidden.</y-description> 342 + <test-description>Skip content with visibility:hidden.</test-description> 341 343 <div>小ぢん<span style="visibility: hidden;">content</span>まり1</div> 342 - </y-test> 344 + </test-case> 343 345 344 - <y-test 346 + <test-case 345 347 data-test-data='{ 346 348 "node": "div", 347 349 "offset": 0, ··· 353 355 } 354 356 }' 355 357 > 356 - <y-description>Skip content with display:none.</y-description> 358 + <test-description>Skip content with display:none.</test-description> 357 359 <div>小ぢん<span style="display: none;">content</span>まり1</div> 358 - </y-test> 360 + </test-case> 359 361 360 - <y-test 362 + <test-case 361 363 data-test-data='{ 362 364 "node": "div", 363 365 "offset": 0, ··· 369 371 } 370 372 }' 371 373 > 372 - <y-description>Don't skip content with user-select:none.</y-description> 374 + <test-description>Don't skip content with user-select:none.</test-description> 373 375 <div>小ぢ<span style="user-select: none;">ん</span>まり1</div> 374 - </y-test> 376 + </test-case> 375 377 376 - <y-test 378 + <test-case 377 379 data-test-data='{ 378 380 "node": "div", 379 381 "offset": 0, ··· 385 387 } 386 388 }' 387 389 > 388 - <y-description>Skip content with user-select:none <em>and</em> a transparent color.</y-description> 390 + <test-description>Skip content with user-select:none <em>and</em> a transparent color.</test-description> 389 391 <div>小ぢん<span style="user-select: none; color: rgba(0, 0, 0, 0);">content</span>まり1</div> 390 - </y-test> 392 + </test-case> 391 393 392 394 </body> 393 395 </html>
+4 -8
test/data/html/test-stylesheet.css
··· 19 19 margin: 0.33em 0; 20 20 } 21 21 22 - h1+p, 23 - h1+y-description { 22 + h1+test-description { 24 23 margin-top: -0.67em; 25 24 } 26 25 ··· 29 28 text-decoration: underline; 30 29 } 31 30 32 - .test, 33 - y-test { 31 + test-case { 34 32 display: block; 35 33 background-color: #ffffff; 36 34 margin: 1em 0; ··· 39 37 border-radius: 4px; 40 38 } 41 39 42 - .test::before, 43 - y-test::before { 40 + test-case::before { 44 41 content: 'Test ' counter(test-id); 45 42 display: block; 46 43 counter-increment: test-id; ··· 49 46 font-weight: bold; 50 47 } 51 48 52 - .description, 53 - y-description { 49 + test-description { 54 50 color: #444444; 55 51 font-style: italic; 56 52 display: block;
+1 -1
test/document-util.test.js
··· 109 109 return document.querySelector('div[style*="2147483646"]>*'); 110 110 } 111 111 112 - const test = createDomTest(path.join(dirname, 'data/html/test-document1.html')); 112 + const test = createDomTest(path.join(dirname, 'data/html/document-util.html')); 113 113 114 114 describe('DocumentUtil', () => { 115 115 test('Text scanning functions', ({window}) => {
+2 -2
test/dom-text-scanner.test.js
··· 102 102 } 103 103 104 104 105 - const test = createDomTest(path.join(dirname, 'data/html/test-dom-text-scanner.html')); 105 + const test = createDomTest(path.join(dirname, 'data/html/dom-text-scanner.html')); 106 106 107 107 describe('DOMTextScanner', () => { 108 108 test('Seek tests', ({window}) => { 109 109 const {document} = window; 110 110 window.getComputedStyle = createAbsoluteGetComputedStyle(window); 111 111 112 - for (const testElement of /** @type {NodeListOf<HTMLElement>} */ (document.querySelectorAll('y-test'))) { 112 + for (const testElement of /** @type {NodeListOf<HTMLElement>} */ (document.querySelectorAll('test-case'))) { 113 113 /** @type {import('test/dom-text-scanner').TestData|import('test/dom-text-scanner').TestData[]} */ 114 114 let testData = parseJson(/** @type {string} */ (testElement.dataset.testData)); 115 115 if (!Array.isArray(testData)) {
+6 -10
test/playwright/visual.spec.js
··· 16 16 */ 17 17 18 18 import path from 'path'; 19 - 20 - import { 21 - expect, 22 - root, 23 - test 24 - } from './playwright-util'; 19 + import {pathToFileURL} from 'url'; 20 + import {expect, root, test} from './playwright-util'; 25 21 26 22 test.beforeEach(async ({context}) => { 27 23 // wait for the on-install welcome.html tab to load, which becomes the foreground tab ··· 86 82 await (await /** @type {import('@playwright/test').Frame} */ (popup_frame).frameElement()).waitForElementState('hidden'); // wait for popup to disappear 87 83 }; 88 84 89 - // Load test-document1.html 90 - await page.goto('file://' + path.join(root, 'test/data/html/test-document1.html')); 85 + // Test document 1 86 + await page.goto(pathToFileURL(path.join(root, 'test/data/html/document-util.html')).toString()); 91 87 await page.setViewportSize({width: 1000, height: 1800}); 92 88 await page.keyboard.down('Shift'); 93 89 let i = 1; ··· 96 92 i++; 97 93 } 98 94 99 - // Load test-document2.html 100 - await page.goto('file://' + path.join(root, 'test/data/html/test-document2.html')); 95 + // Test document 2 96 + await page.goto(pathToFileURL(path.join(root, 'test/data/html/popup-tests.html')).toString()); 101 97 await page.setViewportSize({width: 1000, height: 4500}); 102 98 await page.keyboard.down('Shift'); 103 99 i = 1;