Bug 1905944: Fix intermittents in browser_tab_preview.js r=sthompson,tabbrowser-reviewers, a=test-only
This patch fixes a number of issues that clear up a few different intermittents in browser_tab_preview.js. 1. In browser_tab_groups_tab_interactions_telemetry.js, a call to "close duplicate tabs" would automatically open the confirmation hint panel. If not manually closed, it seems to persist in a half-way open state where the `animating` attribute is always `true`. This is now fixed. 2. There is a test somewhere that seems to apply the `sidebar.verticalTabs` pref and doesn't turn it off. I would like to figure out which test is causing this, but as a last defence I have made sure this is always properly set within this test suite. 3. Some tests check that THP is disabled if another panel is open. These used to work by opening the `appMenu-popup` menu (the hamburger menu in the top right of the browser). The problem with this approach is that this panel (and basically every other panel) are very complex and are prone to change. This was causing an intermittent failure where attempting to close this panel threw an error in console that seemed to be specifically related to this panel. I fixed this by creating a fake minimal panel that is guaranteed to not change as application code changes. (I borrowed this technique from https://searchfox.org/mozilla-central/source/browser/base/content/test/popupNotifications/browser_popupNotification_queue.js). 4. There is a suite of tests that checks that THP is disabled in the event that a drag operation is performed. The problem is that dragging a tab by 100px sometimes detaches the tab and creates a new window, breaking the test run. Reducing the drag amount seems to fix this. 5. As a last line of defence, I have added a state reset function at the start of each test to ensure that all panels are closed and that the mouse is not hovering over the tab strip. (The latter was being done at the end of some tests already, but this makes sure it is consistently applied everywhere.) Closes bug1898099, bug1905944, bug1933597. Differential Revision: https://phabricator.services.mozilla.com/D258976
This commit is contained in:
committed by
rvandermeulen@mozilla.com
parent
2ce3f80962
commit
520c64e4d9
@@ -295,6 +295,13 @@ add_task(async function test_tabInteractionsCloseViaAnotherTabContext() {
|
|||||||
);
|
);
|
||||||
await assertMetricFoundFor("close_tab_other", 4);
|
await assertMetricFoundFor("close_tab_other", 4);
|
||||||
|
|
||||||
|
// Dismiss the confirmation panel that appears after closing duplicate tabs.
|
||||||
|
EventUtils.synthesizeMouseAtCenter(document.documentElement, {});
|
||||||
|
await BrowserTestUtils.waitForCondition(
|
||||||
|
() => !window.ConfirmationHint._panel.getAttribute("animating"),
|
||||||
|
"Ensure the confirmation panel is closed"
|
||||||
|
);
|
||||||
|
|
||||||
window.gBrowser.removeAllTabsBut(initialTab);
|
window.gBrowser.removeAllTabsBut(initialTab);
|
||||||
await resetTelemetry();
|
await resetTelemetry();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -42,15 +42,53 @@ async function closePreviews(win = window) {
|
|||||||
return previewHidden;
|
return previewHidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getOpenPanels() {
|
||||||
|
return document.querySelectorAll(
|
||||||
|
"panel[panelopen=true],panel[animating=true],menupopup[open=true]"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function resetState() {
|
||||||
|
for (let panel of getOpenPanels()) {
|
||||||
|
let hiddenEvent = BrowserTestUtils.waitForPopupEvent(panel, "hidden");
|
||||||
|
panel.hidePopup();
|
||||||
|
await hiddenEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
let openPanels = getOpenPanels();
|
||||||
|
Assert.ok(!openPanels.length, `sanity check: no panels open`);
|
||||||
|
|
||||||
|
// Ensure the mouse is not hovering over the tab strip.
|
||||||
|
EventUtils.synthesizeMouseAtCenter(document.documentElement, {
|
||||||
|
type: "mouseover",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function createFakePanel(win = window) {
|
||||||
|
let panel = win.document.createXULElement("panel");
|
||||||
|
// Necessary to get the panel open, animating, etc. elements to appear.
|
||||||
|
panel.setAttribute("type", "arrow");
|
||||||
|
win.document.documentElement.appendChild(panel);
|
||||||
|
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
add_setup(async function () {
|
add_setup(async function () {
|
||||||
await SpecialPowers.pushPrefEnv({
|
await SpecialPowers.pushPrefEnv({
|
||||||
set: [
|
set: [
|
||||||
["browser.tabs.hoverPreview.enabled", true],
|
["browser.tabs.hoverPreview.enabled", true],
|
||||||
["browser.tabs.hoverPreview.showThumbnails", false],
|
["browser.tabs.hoverPreview.showThumbnails", false],
|
||||||
["browser.tabs.tooltipsShowPidAndActiveness", false],
|
["browser.tabs.tooltipsShowPidAndActiveness", false],
|
||||||
|
["sidebar.revamp", false],
|
||||||
|
["sidebar.verticalTabs", false],
|
||||||
["ui.tooltip.delay_ms", 0],
|
["ui.tooltip.delay_ms", 0],
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await resetState();
|
||||||
|
registerCleanupFunction(async function () {
|
||||||
|
await resetState();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -88,10 +126,7 @@ add_task(async function hoverTests() {
|
|||||||
BrowserTestUtils.removeTab(tab1);
|
BrowserTestUtils.removeTab(tab1);
|
||||||
BrowserTestUtils.removeTab(tab2);
|
BrowserTestUtils.removeTab(tab2);
|
||||||
|
|
||||||
// Move the mouse outside of the tab strip.
|
await resetState();
|
||||||
EventUtils.synthesizeMouseAtCenter(document.documentElement, {
|
|
||||||
type: "mouseover",
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Bug 1897475 - don't show tab previews in background windows
|
// Bug 1897475 - don't show tab previews in background windows
|
||||||
@@ -140,11 +175,8 @@ add_task(async function noTabPreviewInBackgroundWindowTests() {
|
|||||||
|
|
||||||
BrowserTestUtils.removeTab(bgTab);
|
BrowserTestUtils.removeTab(bgTab);
|
||||||
|
|
||||||
// Move the mouse outside of the tab strip.
|
|
||||||
EventUtils.synthesizeMouseAtCenter(document.documentElement, {
|
|
||||||
type: "mouseover",
|
|
||||||
});
|
|
||||||
sinon.restore();
|
sinon.restore();
|
||||||
|
await resetState();
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -179,10 +211,7 @@ add_task(async function focusTests() {
|
|||||||
BrowserTestUtils.removeTab(tab1);
|
BrowserTestUtils.removeTab(tab1);
|
||||||
BrowserTestUtils.removeTab(tab2);
|
BrowserTestUtils.removeTab(tab2);
|
||||||
|
|
||||||
// Move the mouse outside of the tab strip.
|
await resetState();
|
||||||
EventUtils.synthesizeMouseAtCenter(document.documentElement, {
|
|
||||||
type: "mouseover",
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -208,13 +237,8 @@ add_task(async function pidAndActivenessHiddenByDefaultTests() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await closePreviews();
|
await closePreviews();
|
||||||
|
|
||||||
BrowserTestUtils.removeTab(tab1);
|
BrowserTestUtils.removeTab(tab1);
|
||||||
|
await resetState();
|
||||||
// Move the mouse outside of the tab strip.
|
|
||||||
EventUtils.synthesizeMouseAtCenter(document.documentElement, {
|
|
||||||
type: "mouseover",
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
add_task(async function pidAndActivenessTests() {
|
add_task(async function pidAndActivenessTests() {
|
||||||
@@ -271,11 +295,7 @@ add_task(async function pidAndActivenessTests() {
|
|||||||
BrowserTestUtils.removeTab(tab1);
|
BrowserTestUtils.removeTab(tab1);
|
||||||
BrowserTestUtils.removeTab(tab2);
|
BrowserTestUtils.removeTab(tab2);
|
||||||
await SpecialPowers.popPrefEnv();
|
await SpecialPowers.popPrefEnv();
|
||||||
|
await resetState();
|
||||||
// Move the mouse outside of the tab strip.
|
|
||||||
EventUtils.synthesizeMouseAtCenter(document.documentElement, {
|
|
||||||
type: "mouseover",
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -334,11 +354,7 @@ add_task(async function thumbnailTests() {
|
|||||||
|
|
||||||
// Removing the tab should close the preview.
|
// Removing the tab should close the preview.
|
||||||
await previewHidden;
|
await previewHidden;
|
||||||
|
await resetState();
|
||||||
// Move the mouse outside of the tab strip.
|
|
||||||
EventUtils.synthesizeMouseAtCenter(document.documentElement, {
|
|
||||||
type: "mouseover",
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -396,11 +412,7 @@ add_task(async function wireframeTests() {
|
|||||||
|
|
||||||
// Removing the tab should close the preview.
|
// Removing the tab should close the preview.
|
||||||
await previewHidden;
|
await previewHidden;
|
||||||
|
await resetState();
|
||||||
// Move the mouse outside of the tab strip.
|
|
||||||
EventUtils.synthesizeMouseAtCenter(document.documentElement, {
|
|
||||||
type: "mouseover",
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -447,6 +459,7 @@ add_task(async function delayTests() {
|
|||||||
BrowserTestUtils.removeTab(tab1);
|
BrowserTestUtils.removeTab(tab1);
|
||||||
BrowserTestUtils.removeTab(tab2);
|
BrowserTestUtils.removeTab(tab2);
|
||||||
sinon.restore();
|
sinon.restore();
|
||||||
|
await resetState();
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -474,7 +487,7 @@ add_task(async function dragTests() {
|
|||||||
EventUtils.synthesizePlainDragAndDrop({
|
EventUtils.synthesizePlainDragAndDrop({
|
||||||
srcElement: tab1,
|
srcElement: tab1,
|
||||||
destElement: null,
|
destElement: null,
|
||||||
stepX: 100,
|
stepX: 5,
|
||||||
stepY: 0,
|
stepY: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -489,12 +502,8 @@ add_task(async function dragTests() {
|
|||||||
BrowserTestUtils.removeTab(tab1);
|
BrowserTestUtils.removeTab(tab1);
|
||||||
sinon.restore();
|
sinon.restore();
|
||||||
|
|
||||||
// Move the mouse outside of the tab strip.
|
|
||||||
EventUtils.synthesizeMouseAtCenter(document.documentElement, {
|
|
||||||
type: "mouseover",
|
|
||||||
});
|
|
||||||
|
|
||||||
await SpecialPowers.popPrefEnv();
|
await SpecialPowers.popPrefEnv();
|
||||||
|
await resetState();
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -537,11 +546,7 @@ add_task(async function panelSuppressionOnContextMenuTests() {
|
|||||||
contentAreaContextMenu.hidePopup();
|
contentAreaContextMenu.hidePopup();
|
||||||
BrowserTestUtils.removeTab(tab);
|
BrowserTestUtils.removeTab(tab);
|
||||||
sinon.restore();
|
sinon.restore();
|
||||||
|
await resetState();
|
||||||
// Move the mouse outside of the tab strip.
|
|
||||||
EventUtils.synthesizeMouseAtCenter(document.documentElement, {
|
|
||||||
type: "mouseover",
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -559,11 +564,13 @@ add_task(async function panelSuppressionOnPanelTests() {
|
|||||||
const previewComponent = gBrowser.tabContainer.previewPanel;
|
const previewComponent = gBrowser.tabContainer.previewPanel;
|
||||||
sinon.spy(previewComponent, "activate");
|
sinon.spy(previewComponent, "activate");
|
||||||
|
|
||||||
// The `openPopup` API appears to not be working for this panel,
|
let fakePanel = createFakePanel();
|
||||||
// but it can be triggered by firing a click event on the associated button.
|
const popupShownEvent = BrowserTestUtils.waitForPopupEvent(
|
||||||
const appMenuButton = document.getElementById("PanelUI-menu-button");
|
fakePanel,
|
||||||
const appMenuPopup = document.getElementById("appMenu-popup");
|
"shown"
|
||||||
appMenuButton.click();
|
);
|
||||||
|
fakePanel.openPopup();
|
||||||
|
await popupShownEvent;
|
||||||
|
|
||||||
EventUtils.synthesizeMouseAtCenter(tab, { type: "mouseover" }, window);
|
EventUtils.synthesizeMouseAtCenter(tab, { type: "mouseover" }, window);
|
||||||
|
|
||||||
@@ -584,12 +591,12 @@ add_task(async function panelSuppressionOnPanelTests() {
|
|||||||
window
|
window
|
||||||
);
|
);
|
||||||
|
|
||||||
const popupHidingEvent = BrowserTestUtils.waitForEvent(
|
const popupHiddenEvent = BrowserTestUtils.waitForPopupEvent(
|
||||||
appMenuPopup,
|
fakePanel,
|
||||||
"popuphiding"
|
"hidden"
|
||||||
);
|
);
|
||||||
appMenuPopup.hidePopup();
|
fakePanel.hidePopup();
|
||||||
await popupHidingEvent;
|
await popupHiddenEvent;
|
||||||
|
|
||||||
// Attempt to open the tab preview immediately after the popup hiding event
|
// Attempt to open the tab preview immediately after the popup hiding event
|
||||||
await openPreview(tab);
|
await openPreview(tab);
|
||||||
@@ -597,11 +604,8 @@ add_task(async function panelSuppressionOnPanelTests() {
|
|||||||
|
|
||||||
BrowserTestUtils.removeTab(tab);
|
BrowserTestUtils.removeTab(tab);
|
||||||
sinon.restore();
|
sinon.restore();
|
||||||
|
fakePanel.remove();
|
||||||
// Move the mouse outside of the tab strip.
|
await resetState();
|
||||||
EventUtils.synthesizeMouseAtCenter(document.documentElement, {
|
|
||||||
type: "mouseover",
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -614,11 +618,13 @@ add_task(async function panelSuppressionOnPanelLazyLoadTests() {
|
|||||||
let fgWindow = await BrowserTestUtils.openNewBrowserWindow();
|
let fgWindow = await BrowserTestUtils.openNewBrowserWindow();
|
||||||
let fgTab = fgWindow.gBrowser.tabs[0];
|
let fgTab = fgWindow.gBrowser.tabs[0];
|
||||||
|
|
||||||
// The `openPopup` API appears to not be working for this panel,
|
let fakePanel = createFakePanel(fgWindow);
|
||||||
// but it can be triggered by firing a click event on the associated button.
|
const popupShownEvent = BrowserTestUtils.waitForPopupEvent(
|
||||||
const appMenuButton = fgWindow.document.getElementById("PanelUI-menu-button");
|
fakePanel,
|
||||||
const appMenuPopup = fgWindow.document.getElementById("appMenu-popup");
|
"shown"
|
||||||
appMenuButton.click();
|
);
|
||||||
|
fakePanel.openPopup();
|
||||||
|
await popupShownEvent;
|
||||||
|
|
||||||
EventUtils.synthesizeMouseAtCenter(fgTab, { type: "mouseover" }, fgWindow);
|
EventUtils.synthesizeMouseAtCenter(fgTab, { type: "mouseover" }, fgWindow);
|
||||||
|
|
||||||
@@ -626,8 +632,8 @@ add_task(async function panelSuppressionOnPanelLazyLoadTests() {
|
|||||||
// Sometimes the tests run slower than the test browser -- it's not always possible
|
// Sometimes the tests run slower than the test browser -- it's not always possible
|
||||||
// to catch the panel in its opening state, so we have to check for both states.
|
// to catch the panel in its opening state, so we have to check for both states.
|
||||||
return (
|
return (
|
||||||
(appMenuPopup.getAttribute("animating") === "true" ||
|
(fakePanel.getAttribute("animating") === "true" ||
|
||||||
appMenuPopup.getAttribute("panelopen") === "true") &&
|
fakePanel.getAttribute("panelopen") === "true") &&
|
||||||
fgWindow.gBrowser.tabContainer.previewPanel !== null
|
fgWindow.gBrowser.tabContainer.previewPanel !== null
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -635,7 +641,7 @@ add_task(async function panelSuppressionOnPanelLazyLoadTests() {
|
|||||||
|
|
||||||
// We can't spy on the previewComponent and check for calls to `activate` like in other tests,
|
// We can't spy on the previewComponent and check for calls to `activate` like in other tests,
|
||||||
// since we can't guarantee that the spy will be set up before the call is made.
|
// since we can't guarantee that the spy will be set up before the call is made.
|
||||||
// Therefore the only realiable way to test that the popup isn't open is to reach in and check
|
// Therefore the only reliable way to test that the popup isn't open is to reach in and check
|
||||||
// that it is in a disabled state.
|
// that it is in a disabled state.
|
||||||
Assert.equal(previewComponent._isDisabled(), true, "");
|
Assert.equal(previewComponent._isDisabled(), true, "");
|
||||||
|
|
||||||
@@ -651,20 +657,17 @@ add_task(async function panelSuppressionOnPanelLazyLoadTests() {
|
|||||||
fgWindow
|
fgWindow
|
||||||
);
|
);
|
||||||
|
|
||||||
const popupHidingEvent = BrowserTestUtils.waitForEvent(
|
const popupHiddenEvent = BrowserTestUtils.waitForPopupEvent(
|
||||||
appMenuPopup,
|
fakePanel,
|
||||||
"popuphiding"
|
"hidden"
|
||||||
);
|
);
|
||||||
appMenuPopup.hidePopup();
|
fakePanel.hidePopup();
|
||||||
await popupHidingEvent;
|
await popupHiddenEvent;
|
||||||
|
|
||||||
BrowserTestUtils.removeTab(fgTab);
|
BrowserTestUtils.removeTab(fgTab);
|
||||||
|
fakePanel.remove();
|
||||||
// Move the mouse outside of the tab strip.
|
|
||||||
await BrowserTestUtils.closeWindow(fgWindow);
|
await BrowserTestUtils.closeWindow(fgWindow);
|
||||||
EventUtils.synthesizeMouseAtCenter(document.documentElement, {
|
await resetState();
|
||||||
type: "mouseover",
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -712,12 +715,13 @@ add_task(async function otherPanelOpenTests() {
|
|||||||
|
|
||||||
Assert.ok(previewComponent._panelOpener._timer, "Timer is set");
|
Assert.ok(previewComponent._panelOpener._timer, "Timer is set");
|
||||||
|
|
||||||
// Open the popup before the timer finishes...
|
let fakePanel = createFakePanel();
|
||||||
const appMenuButton = document.getElementById("PanelUI-menu-button");
|
const popupShownEvent = BrowserTestUtils.waitForPopupEvent(
|
||||||
const appMenuPopup = document.getElementById("appMenu-popup");
|
fakePanel,
|
||||||
appMenuButton.click();
|
"shown"
|
||||||
|
);
|
||||||
await BrowserTestUtils.waitForEvent(appMenuPopup, "popupshown");
|
fakePanel.openPopup();
|
||||||
|
await popupShownEvent;
|
||||||
|
|
||||||
// Wait for timer to finish...
|
// Wait for timer to finish...
|
||||||
await BrowserTestUtils.waitForCondition(
|
await BrowserTestUtils.waitForCondition(
|
||||||
@@ -738,16 +742,17 @@ add_task(async function otherPanelOpenTests() {
|
|||||||
type: "mouseout",
|
type: "mouseout",
|
||||||
});
|
});
|
||||||
|
|
||||||
const popupHidingEvent = BrowserTestUtils.waitForEvent(
|
const popupHiddenEvent = BrowserTestUtils.waitForPopupEvent(
|
||||||
appMenuPopup,
|
fakePanel,
|
||||||
"popuphiding"
|
"hidden"
|
||||||
);
|
);
|
||||||
appMenuPopup.hidePopup();
|
fakePanel.hidePopup();
|
||||||
await popupHidingEvent;
|
await popupHiddenEvent;
|
||||||
|
|
||||||
|
fakePanel.remove();
|
||||||
sinon.restore();
|
sinon.restore();
|
||||||
|
|
||||||
await SpecialPowers.popPrefEnv();
|
await SpecialPowers.popPrefEnv();
|
||||||
|
await resetState();
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -782,6 +787,7 @@ add_task(async function urlBarInputTests() {
|
|||||||
Assert.equal(previewElement.state, "closed", "Preview is closed");
|
Assert.equal(previewElement.state, "closed", "Preview is closed");
|
||||||
|
|
||||||
BrowserTestUtils.removeTab(tab1);
|
BrowserTestUtils.removeTab(tab1);
|
||||||
|
await resetState();
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -812,8 +818,8 @@ add_task(async function zeroDelayTests() {
|
|||||||
|
|
||||||
await closePreviews();
|
await closePreviews();
|
||||||
BrowserTestUtils.removeTab(tab);
|
BrowserTestUtils.removeTab(tab);
|
||||||
|
|
||||||
await SpecialPowers.popPrefEnv();
|
await SpecialPowers.popPrefEnv();
|
||||||
|
await resetState();
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -852,11 +858,7 @@ add_task(async function wheelTests() {
|
|||||||
while (gBrowser.tabs.length > 1) {
|
while (gBrowser.tabs.length > 1) {
|
||||||
BrowserTestUtils.removeTab(gBrowser.tabs[0]);
|
BrowserTestUtils.removeTab(gBrowser.tabs[0]);
|
||||||
}
|
}
|
||||||
|
await resetState();
|
||||||
// Move the mouse outside of the tab strip.
|
|
||||||
EventUtils.synthesizeMouseAtCenter(document.documentElement, {
|
|
||||||
type: "mouseover",
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
add_task(async function appearsAsTooltipToAccessibilityToolsTests() {
|
add_task(async function appearsAsTooltipToAccessibilityToolsTests() {
|
||||||
@@ -903,6 +905,7 @@ add_task(async function tabContentChangeTests() {
|
|||||||
|
|
||||||
await closePreviews();
|
await closePreviews();
|
||||||
BrowserTestUtils.removeTab(tab);
|
BrowserTestUtils.removeTab(tab);
|
||||||
|
await resetState();
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -934,4 +937,5 @@ add_task(async function tabPreview_verticalTabsPositioning() {
|
|||||||
|
|
||||||
await closePreviews();
|
await closePreviews();
|
||||||
BrowserTestUtils.removeTab(tab);
|
BrowserTestUtils.removeTab(tab);
|
||||||
|
await resetState();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user