diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /devtools/client/netmonitor/test/browser_net_filter-01.js | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/client/netmonitor/test/browser_net_filter-01.js')
-rw-r--r-- | devtools/client/netmonitor/test/browser_net_filter-01.js | 558 |
1 files changed, 558 insertions, 0 deletions
diff --git a/devtools/client/netmonitor/test/browser_net_filter-01.js b/devtools/client/netmonitor/test/browser_net_filter-01.js new file mode 100644 index 0000000000..f72fb4d8c5 --- /dev/null +++ b/devtools/client/netmonitor/test/browser_net_filter-01.js @@ -0,0 +1,558 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Used to test filtering a unicode URI component +const UNICODE_IN_URI_COMPONENT = "\u6e2c"; +const ENCODED_CHARS_IN_URI_COMP = encodeURIComponent(UNICODE_IN_URI_COMPONENT); + +// Used to test filtering an international domain name with Unicode +const IDN = "xn--hxajbheg2az3al.xn--jxalpdlp"; +const UNICODE_IN_IDN = "\u03c0\u03b1"; + +/** + * Test if filtering items in the network table works correctly. + */ +const BASIC_REQUESTS = [ + { + url: getSjsURLInUnicodeIdn() + "?fmt=html&res=undefined&text=Sample&cors=1", + }, + { url: "sjs_content-type-test-server.sjs?fmt=css&text=sample" }, + { url: "sjs_content-type-test-server.sjs?fmt=js&text=sample" }, + { + url: `sjs_content-type-test-server.sjs?fmt=html&text=${ENCODED_CHARS_IN_URI_COMP}`, + }, + { + url: `sjs_content-type-test-server.sjs?fmt=css&text=${ENCODED_CHARS_IN_URI_COMP}`, + }, + { + url: `sjs_content-type-test-server.sjs?fmt=js&text=${ENCODED_CHARS_IN_URI_COMP}`, + }, +]; + +const REQUESTS_WITH_MEDIA = BASIC_REQUESTS.concat([ + { url: getSjsURLInUnicodeIdn() + "?fmt=font&cors=1" }, + { url: "sjs_content-type-test-server.sjs?fmt=image" }, + { url: "sjs_content-type-test-server.sjs?fmt=audio" }, + { url: "sjs_content-type-test-server.sjs?fmt=application-ogg" }, + { url: "sjs_content-type-test-server.sjs?fmt=video" }, + { url: "sjs_content-type-test-server.sjs?fmt=hls-m3u8" }, + { url: "sjs_content-type-test-server.sjs?fmt=hls-m3u8-alt-mime-type" }, +]); + +const REQUESTS_WITH_MEDIA_AND_FLASH = REQUESTS_WITH_MEDIA.concat([ + { url: "sjs_content-type-test-server.sjs?fmt=flash" }, +]); + +const REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS = + REQUESTS_WITH_MEDIA_AND_FLASH.concat([ + /* Use new WebSocket() to mock native websocket request, then "Upgrade" will be added */ + { url: WS_URL + "sjs_content-type-test-server.sjs?fmt=ws", ws: true }, + ]); + +const EXPECTED_REQUESTS = [ + { + method: "GET", + url: getSjsURLInUnicodeIdn() + "?fmt=html&res=undefined&text=Sample&cors=1", + data: { + fuzzyUrl: true, + status: 200, + statusText: "OK", + type: "html", + fullMimeType: "text/html; charset=utf-8", + }, + }, + { + method: "GET", + url: CONTENT_TYPE_SJS + "?fmt=css&text=sample", + data: { + fuzzyUrl: true, + status: 200, + statusText: "OK", + type: "css", + fullMimeType: "text/css; charset=utf-8", + }, + }, + { + method: "GET", + url: CONTENT_TYPE_SJS + "?fmt=js&text=sample", + data: { + fuzzyUrl: true, + status: 200, + statusText: "OK", + type: "js", + fullMimeType: "application/javascript; charset=utf-8", + }, + }, + { + method: "GET", + url: CONTENT_TYPE_SJS + `?fmt=html&text=${ENCODED_CHARS_IN_URI_COMP}`, + data: { + fuzzyUrl: true, + status: 200, + statusText: "OK", + type: "html", + fullMimeType: "text/html; charset=utf-8", + }, + }, + { + method: "GET", + url: CONTENT_TYPE_SJS + `?fmt=css&text=${ENCODED_CHARS_IN_URI_COMP}`, + data: { + fuzzyUrl: true, + status: 200, + statusText: "OK", + type: "css", + fullMimeType: "text/css; charset=utf-8", + }, + }, + { + method: "GET", + url: CONTENT_TYPE_SJS + `?fmt=js&text=${ENCODED_CHARS_IN_URI_COMP}`, + data: { + fuzzyUrl: true, + status: 200, + statusText: "OK", + type: "js", + fullMimeType: "application/javascript; charset=utf-8", + }, + }, + { + method: "GET", + url: getSjsURLInUnicodeIdn() + "?fmt=font&cors=1", + data: { + fuzzyUrl: true, + status: 200, + statusText: "OK", + type: "woff", + fullMimeType: "font/woff", + }, + }, + { + method: "GET", + url: CONTENT_TYPE_SJS + "?fmt=image", + data: { + fuzzyUrl: true, + status: 200, + statusText: "OK", + type: "png", + fullMimeType: "image/png", + }, + }, + { + method: "GET", + url: CONTENT_TYPE_SJS + "?fmt=audio", + data: { + fuzzyUrl: true, + status: 200, + statusText: "OK", + type: "ogg", + fullMimeType: "audio/ogg", + }, + }, + { + method: "GET", + url: CONTENT_TYPE_SJS + "?fmt=application-ogg", + data: { + fuzzyUrl: true, + status: 200, + statusText: "OK", + type: "ogg", + fullMimeType: "application/ogg", + }, + }, + { + method: "GET", + url: CONTENT_TYPE_SJS + "?fmt=video", + data: { + fuzzyUrl: true, + status: 200, + statusText: "OK", + type: "webm", + fullMimeType: "video/webm", + }, + }, + { + method: "GET", + url: CONTENT_TYPE_SJS + "?fmt=hls-m3u8", + data: { + fuzzyUrl: true, + status: 200, + statusText: "OK", + type: "x-mpegurl", + fullMimeType: "application/x-mpegurl", + }, + }, + { + method: "GET", + url: CONTENT_TYPE_SJS + "?fmt=hls-m3u8-alt-mime-type", + data: { + fuzzyUrl: true, + status: 200, + statusText: "OK", + type: "vnd.apple.mpegurl", + fullMimeType: "application/vnd.apple.mpegurl", + }, + }, + { + method: "GET", + url: CONTENT_TYPE_SJS + "?fmt=flash", + data: { + fuzzyUrl: true, + status: 200, + statusText: "OK", + type: "x-shockwave-flash", + fullMimeType: "application/x-shockwave-flash", + }, + }, + { + method: "GET", + url: WS_WS_CONTENT_TYPE_SJS + "?fmt=ws", + data: { + fuzzyUrl: true, + status: 101, + statusText: "Switching Protocols", + }, + }, +]; + +add_task(async function () { + const { monitor } = await initNetMonitor(FILTERING_URL, { requestCount: 1 }); + const { document, store, windowRequire } = monitor.panelWin; + const Actions = windowRequire("devtools/client/netmonitor/src/actions/index"); + const { getDisplayedRequests, getSelectedRequest, getSortedRequests } = + windowRequire("devtools/client/netmonitor/src/selectors/index"); + + store.dispatch(Actions.batchEnable(false)); + + function setFreetextFilter(value) { + store.dispatch(Actions.setRequestFilterText(value)); + } + + info("Starting test... "); + + const wait = waitForNetworkEvents( + monitor, + REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS.length + ); + await performRequestsInContent(REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS); + await wait; + + EventUtils.sendMouseEvent( + { type: "mousedown" }, + document.querySelectorAll(".request-list-item")[0] + ); + + isnot( + getSelectedRequest(store.getState()), + null, + "There should be a selected item in the requests menu." + ); + is( + getSelectedIndex(store.getState()), + 0, + "The first item should be selected in the requests menu." + ); + is( + !!document.querySelector(".network-details-bar"), + true, + "The network details panel should render correctly." + ); + + // First test with single filters... + testFilterButtons(monitor, "all"); + await testContents([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]); + + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-html-button") + ); + testFilterButtons(monitor, "html"); + await testContents([1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + + // Reset filters + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-all-button") + ); + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-css-button") + ); + testFilterButtons(monitor, "css"); + await testContents([0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-all-button") + ); + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-js-button") + ); + testFilterButtons(monitor, "js"); + await testContents([0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-all-button") + ); + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-xhr-button") + ); + testFilterButtons(monitor, "xhr"); + await testContents([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]); + + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-all-button") + ); + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-fonts-button") + ); + testFilterButtons(monitor, "fonts"); + await testContents([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]); + + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-all-button") + ); + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-images-button") + ); + testFilterButtons(monitor, "images"); + await testContents([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]); + + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-all-button") + ); + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-media-button") + ); + testFilterButtons(monitor, "media"); + await testContents([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0]); + + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-all-button") + ); + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-ws-button") + ); + testFilterButtons(monitor, "ws"); + await testContents([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); + + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-all-button") + ); + + testFilterButtons(monitor, "all"); + await testContents([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]); + + // Text in filter box that matches nothing should hide all. + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-all-button") + ); + setFreetextFilter("foobar"); + await testContents([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + + // ASCII text in filter box that matches should filter out everything else. + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-all-button") + ); + setFreetextFilter("sample"); + await testContents([1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + + // ASCII text in filter box that matches should filter out everything else. + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-all-button") + ); + setFreetextFilter("SAMPLE"); + await testContents([1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + + // Test negative filtering ASCII text(only show unmatched items) + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-all-button") + ); + setFreetextFilter("-sample"); + await testContents([0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]); + + // Unicode text in filter box that matches should filter out everything else. + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-all-button") + ); + setFreetextFilter(UNICODE_IN_URI_COMPONENT); + await testContents([0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + + // Ditto, except the above is for a Unicode URI component, and this one is for + // a Unicode domain name. + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-all-button") + ); + setFreetextFilter(UNICODE_IN_IDN); + await testContents([1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]); + + // Test negative filtering Unicode text(only show unmatched items) + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-all-button") + ); + setFreetextFilter(`-${UNICODE_IN_URI_COMPONENT}`); + await testContents([1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1]); + + // Ditto, except the above is for a Unicode URI component, and this one is for + // a Unicode domain name. + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-all-button") + ); + setFreetextFilter(`-${UNICODE_IN_IDN}`); + await testContents([0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1]); + + // ...then combine multiple filters together. + + // Enable filtering for html and css; should show request of both type. + setFreetextFilter(""); + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-html-button") + ); + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-css-button") + ); + testFilterButtonsCustom(monitor, [0, 1, 1, 0, 0, 0, 0, 0, 0, 0]); + await testContents([1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + + // Html and css filter enabled and text filter should show just the html and css match. + // Should not show both the items matching the button plus the items matching the text. + setFreetextFilter("sample"); + await testContents([1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + setFreetextFilter(UNICODE_IN_URI_COMPONENT); + await testContents([0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + setFreetextFilter(""); + testFilterButtonsCustom(monitor, [0, 1, 1, 0, 0, 0, 0, 0, 0, 0]); + await testContents([1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + + // Disable some filters. Only one left active. + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-css-button") + ); + testFilterButtons(monitor, "html"); + await testContents([1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + + // Disable last active filter. Should toggle to all. + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-html-button") + ); + testFilterButtons(monitor, "all"); + await testContents([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]); + + // Enable few filters and click on all. Only "all" should be checked. + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-html-button") + ); + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-css-button") + ); + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-ws-button") + ); + testFilterButtonsCustom(monitor, [0, 1, 1, 0, 0, 0, 0, 0, 1, 0]); + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector(".requests-list-filter-all-button") + ); + testFilterButtons(monitor, "all"); + await testContents([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]); + + await teardown(monitor); + + function getSelectedIndex(state) { + if (!state.requests.selectedId) { + return -1; + } + return getSortedRequests(state).findIndex( + r => r.id === state.requests.selectedId + ); + } + + async function testContents(visibility) { + const requestItems = document.querySelectorAll(".request-list-item"); + for (const requestItem of requestItems) { + requestItem.scrollIntoView(); + const requestsListStatus = requestItem.querySelector(".status-code"); + EventUtils.sendMouseEvent({ type: "mouseover" }, requestsListStatus); + await waitUntil(() => requestsListStatus.title); + } + + const items = getSortedRequests(store.getState()); + let visibleItems; + + // Filter results will be updated asynchronously, so we should wait until + // displayed requests reach final state. + await waitUntil(() => { + visibleItems = getDisplayedRequests(store.getState()); + return visibleItems.length === visibility.filter(e => e).length; + }); + + is( + items.length, + visibility.length, + "There should be a specific amount of items in the requests menu." + ); + is( + visibleItems.length, + visibility.filter(e => e).length, + "There should be a specific amount of visible items in the requests menu." + ); + + for (let i = 0; i < visibility.length; i++) { + const itemId = items[i].id; + const shouldBeVisible = !!visibility[i]; + const isThere = visibleItems.some(r => r.id == itemId); + + is( + isThere, + shouldBeVisible, + `The item at index ${i} has visibility=${shouldBeVisible}` + ); + + if (shouldBeVisible) { + const { method, url, data } = EXPECTED_REQUESTS[i]; + verifyRequestItemTarget( + document, + getDisplayedRequests(store.getState()), + getSortedRequests(store.getState())[i], + method, + url, + data + ); + } + } + } +}); + +function getSjsURLInUnicodeIdn() { + const { hostname } = new URL(CONTENT_TYPE_SJS); + return CONTENT_TYPE_SJS.replace(hostname, IDN); +} |