Files
upstream-jitsi-meet/tests/pageobjects/VirtualBackgroundDialog.ts
upstream-mirror 1d2bfcac0c
Some checks failed
Prosody Plugin Tests / test (push) Failing after 10m11s
Close stale issues and PRs / stale (push) Failing after 1s
snapshot of https://github.com/jitsi/jitsi-meet.git @ fd1749dd28f4138aa80234fc7f311b19aaffa0e7 (2026-09-15)
2026-09-15 15:56:32 +05:00

140 lines
4.9 KiB
TypeScript

import BaseDialog from './BaseDialog';
const VB_DIALOG_CONTAINER = '#virtual-background-dialog';
const NONE_THUMBNAIL = '[aria-label="Remove background"]';
const SLIGHT_BLUR_THUMBNAIL = '[aria-label="Half Blur"]';
const BLUR_THUMBNAIL = '[aria-label="Blur"]';
/**
* Page object for the Virtual Background tab inside the settings dialog.
*/
export default class VirtualBackgroundDialog extends BaseDialog {
/**
* Waits for the virtual background dialog container to be displayed.
*/
async waitForDisplay(): Promise<void> {
await this.participant.driver.$(VB_DIALOG_CONTAINER).waitForDisplayed({
timeout: 5000,
timeoutMsg: 'Virtual background dialog not displayed'
});
}
/**
* Returns true if the dialog container is currently displayed.
*/
isDisplayed(): Promise<boolean> {
return this.participant.driver.$(VB_DIALOG_CONTAINER).isDisplayed();
}
/**
* Clicks a thumbnail and waits for it to become aria-checked.
* Ensures React has finished re-rendering before the next click, preventing
* rapid clicks from being swallowed during reconciliation.
*
* @param {string} selector - CSS selector for the thumbnail.
* @param {string} label - Human-readable label for logging.
*/
private async clickAndWaitChecked(selector: string, label: string): Promise<void> {
await this.participant.log(`VirtualBackgroundDialog: clicking ${label} thumbnail`);
const el = this.participant.driver.$(selector);
await el.waitForClickable({ timeout: 3000, timeoutMsg: `${label} thumbnail not clickable` });
// Selecting an effect makes the preview (re)load the segmentation model/wasm, which
// saturates the main thread. Two flaky failure modes follow from that:
// 1. A click issued while React is mid-reconciliation (e.g. during rapid switching) is
// dropped — the onClick handler never fires and the thumbnail never becomes checked.
// 2. The first selection of a blur effect triggers a cold model/worker init that blocks
// the main thread for several seconds, delaying the aria-checked re-render (and the
// attribute reads themselves) well past a short timeout.
// Re-issue the click on every poll until aria-checked confirms it landed (covers 1), and
// allow a generous timeout for the cold-start re-render under load (covers 2). The poll
// interval is kept large so a still-pending selection is not needlessly re-triggered.
await this.participant.driver.waitUntil(
async () => {
if (await el.getAttribute('aria-checked') === 'true') {
return true;
}
await el.click();
return false;
},
{
timeout: 15000,
interval: 1500,
timeoutMsg: `${label} thumbnail did not become checked after click`
}
);
}
/**
* Clicks the "Remove background" (None) thumbnail.
*/
clickNone(): Promise<void> {
return this.clickAndWaitChecked(NONE_THUMBNAIL, 'None');
}
/**
* Clicks the "Half Blur" (slight blur) thumbnail.
*/
clickSlightBlur(): Promise<void> {
return this.clickAndWaitChecked(SLIGHT_BLUR_THUMBNAIL, 'Slight Blur');
}
/**
* Clicks the "Blur" (full blur) thumbnail.
*/
clickBlur(): Promise<void> {
return this.clickAndWaitChecked(BLUR_THUMBNAIL, 'Blur');
}
/**
* Returns true if the given thumbnail element has aria-checked="true" (selected in the dialog).
*
* @param {string} selector - CSS selector for the thumbnail element.
*/
async isThumbnailChecked(selector: string): Promise<boolean> {
const el = this.participant.driver.$(selector);
await el.waitForExist({ timeout: 2000 });
return (await el.getAttribute('aria-checked')) === 'true';
}
/**
* Returns true if the None thumbnail is currently selected in the dialog.
*/
isNoneChecked(): Promise<boolean> {
return this.isThumbnailChecked(NONE_THUMBNAIL);
}
/**
* Returns true if the Slight Blur thumbnail is currently selected in the dialog.
*/
isSlightBlurChecked(): Promise<boolean> {
return this.isThumbnailChecked(SLIGHT_BLUR_THUMBNAIL);
}
/**
* Returns true if the Blur thumbnail is currently selected in the dialog.
*/
isBlurChecked(): Promise<boolean> {
return this.isThumbnailChecked(BLUR_THUMBNAIL);
}
/**
* Clicks OK to apply the selected background and close the dialog.
*/
confirm(): Promise<void> {
return this.clickOkButton();
}
/**
* Clicks the X button to cancel without applying any changes.
*/
cancel(): Promise<void> {
return this.clickCloseButton();
}
}