/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; /** * Tests resizing of columns in NetMonitor. */ add_task(async function () { await testForGivenDir("ltr"); await testForGivenDir("rtl"); }); async function testForGivenDir(dir) { if (dir === "rtl") { await pushPref("intl.l10n.pseudo", "bidi"); } else { await pushPref("intl.l10n.pseudo", ""); } // Reset visibleColumns so we only get the default ones // and not all that are set in head.js Services.prefs.clearUserPref("devtools.netmonitor.visibleColumns"); const initialColumnData = Services.prefs.getCharPref( "devtools.netmonitor.columnsData" ); let visibleColumns = JSON.parse( Services.prefs.getCharPref("devtools.netmonitor.visibleColumns") ); // Init network monitor const { monitor } = await initNetMonitor(SIMPLE_URL, { requestCount: 1, }); info("Starting test... "); const { document, windowRequire, store } = monitor.panelWin; const Actions = windowRequire("devtools/client/netmonitor/src/actions/index"); store.dispatch(Actions.batchEnable(false)); // Wait for network events (to have some requests in the table) const wait = waitForNetworkEvents(monitor, 1); await reloadBrowser(); await wait; const headers = document.querySelector(".requests-list-headers"); const parentWidth = headers.getBoundingClientRect().width; // 1. Change File column from 25% (default) to 20% // Size column should then change from 5% (default) to 10% // When File width changes, contentSize should compensate the change. info("Resize file & check changed prefs..."); const fileHeader = document.querySelector(`#requests-list-file-header-box`); resizeColumn(fileHeader, 20, parentWidth, dir); // after resize - get fresh prefs for tests let columnsData = JSON.parse( Services.prefs.getCharPref("devtools.netmonitor.columnsData") ); checkColumnsData(columnsData, "file", 20); checkColumnsData(columnsData, "contentSize", 10); checkSumOfVisibleColumns(columnsData, visibleColumns); // 2. Change Waterfall column width and check that the size // of waterfall changed correctly and all the other columns changed size. info("Resize waterfall & check changed prefs..."); const waterfallHeader = document.querySelector( `#requests-list-waterfall-header-box` ); // before resizing waterfall -> save old columnsData for later testing const oldColumnsData = JSON.parse( Services.prefs.getCharPref("devtools.netmonitor.columnsData") ); resizeWaterfallColumn(waterfallHeader, 30, parentWidth, dir); // 30 fails currently! // after resize - get fresh prefs for tests columnsData = JSON.parse( Services.prefs.getCharPref("devtools.netmonitor.columnsData") ); checkColumnsData(columnsData, "waterfall", 30); checkSumOfVisibleColumns(columnsData, visibleColumns); checkAllColumnsChanged(columnsData, oldColumnsData, visibleColumns); // 3. Check that all rows have the right column sizes. info("Checking alignment of columns and headers..."); const requestsContainer = document.querySelector(".requests-list-row-group"); testColumnsAlignment(headers, requestsContainer); // 4. Hide all columns but size and waterfall // and check that they resize correctly. Then resize // waterfall to 50% => size should take up 50% info("Hide all but 2 columns - size & waterfall and check resizing..."); await hideMoreColumns(monitor, [ "status", "method", "domain", "file", "initiator", "type", "transferred", ]); resizeWaterfallColumn(waterfallHeader, 50, parentWidth, dir); // after resize - get fresh prefs for tests columnsData = JSON.parse( Services.prefs.getCharPref("devtools.netmonitor.columnsData") ); visibleColumns = JSON.parse( Services.prefs.getCharPref("devtools.netmonitor.visibleColumns") ); checkColumnsData(columnsData, "contentSize", 50); checkColumnsData(columnsData, "waterfall", 50); checkSumOfVisibleColumns(columnsData, visibleColumns); // 5. Hide all columns but domain and file // and resize domain to 50% => file should be 50% info("Hide all but 2 columns - domain & file and check resizing..."); await showMoreColumns(monitor, ["domain", "file"]); await hideMoreColumns(monitor, ["contentSize", "waterfall"]); const domainHeader = document.querySelector( `#requests-list-domain-header-box` ); resizeColumn(domainHeader, 50, parentWidth, dir); // after resize - get fresh prefs for tests columnsData = JSON.parse( Services.prefs.getCharPref("devtools.netmonitor.columnsData") ); visibleColumns = JSON.parse( Services.prefs.getCharPref("devtools.netmonitor.visibleColumns") ); checkColumnsData(columnsData, "domain", 50); checkColumnsData(columnsData, "file", 50); checkSumOfVisibleColumns(columnsData, visibleColumns); // Done: clean up. Services.prefs.setCharPref( "devtools.netmonitor.columnsData", initialColumnData ); return teardown(monitor); } async function hideMoreColumns(monitor, arr) { for (let i = 0; i < arr.length; i++) { await hideColumn(monitor, arr[i]); } } async function showMoreColumns(monitor, arr) { for (let i = 0; i < arr.length; i++) { await showColumn(monitor, arr[i]); } } function resizeColumn(columnHeader, newPercent, parentWidth, dir) { const newWidthInPixels = (newPercent * parentWidth) / 100; const win = columnHeader.ownerDocument.defaultView; const currentWidth = columnHeader.getBoundingClientRect().width; const mouseDown = dir === "rtl" ? 0 : currentWidth; const mouseMove = dir === "rtl" ? currentWidth - newWidthInPixels : newWidthInPixels; EventUtils.synthesizeMouse( columnHeader, mouseDown, 1, { type: "mousedown" }, win ); EventUtils.synthesizeMouse( columnHeader, mouseMove, 1, { type: "mousemove" }, win ); EventUtils.synthesizeMouse( columnHeader, mouseMove, 1, { type: "mouseup" }, win ); } function resizeWaterfallColumn(columnHeader, newPercent, parentWidth, dir) { const newWidthInPixels = (newPercent * parentWidth) / 100; const win = columnHeader.ownerDocument.defaultView; const mouseDown = dir === "rtl" ? columnHeader.getBoundingClientRect().right : columnHeader.getBoundingClientRect().left; const mouseMove = dir === "rtl" ? mouseDown + (newWidthInPixels - columnHeader.getBoundingClientRect().width) : mouseDown + (columnHeader.getBoundingClientRect().width - newWidthInPixels); EventUtils.synthesizeMouse( columnHeader.parentElement, mouseDown, 1, { type: "mousedown" }, win ); EventUtils.synthesizeMouse( columnHeader.parentElement, mouseMove, 1, { type: "mousemove" }, win ); EventUtils.synthesizeMouse( columnHeader.parentElement, mouseMove, 1, { type: "mouseup" }, win ); } function checkColumnsData(columnsData, column, expectedWidth) { const widthInPref = Math.round(getWidthFromPref(columnsData, column)); is(widthInPref, expectedWidth, "Column " + column + " has expected size."); } function checkSumOfVisibleColumns(columnsData, visibleColumns) { let sum = 0; visibleColumns.forEach(column => { sum += getWidthFromPref(columnsData, column); }); sum = Math.round(sum); is(sum, 100, "All visible columns cover 100%."); } function getWidthFromPref(columnsData, column) { const widthInPref = columnsData.find(function (element) { return element.name === column; }).width; return widthInPref; } function checkAllColumnsChanged(columnsData, oldColumnsData, visibleColumns) { const oldWaterfallWidth = getWidthFromPref(oldColumnsData, "waterfall"); const newWaterfallWidth = getWidthFromPref(columnsData, "waterfall"); visibleColumns.forEach(column => { // do not test waterfall against waterfall if (column !== "waterfall") { const oldWidth = getWidthFromPref(oldColumnsData, column); const newWidth = getWidthFromPref(columnsData, column); // Test that if waterfall is smaller all other columns are bigger if (oldWaterfallWidth > newWaterfallWidth) { is( oldWidth < newWidth, true, "Column " + column + " has changed width correctly." ); } // Test that if waterfall is bigger all other columns are smaller if (oldWaterfallWidth < newWaterfallWidth) { is( oldWidth > newWidth, true, "Column " + column + " has changed width correctly." ); } } }); }