* Wait for a browser alert to appear and verify its text. Automatically detects * whether a window switch is needed by comparing current window with target window. * If they match, uses normal alert waiting. If different, attempts window switching * but handles the case where Selenium fails
({ text, windowTitle, timeout = this.timeout })
| 1606 | * @returns {Promise<void>} Promise that resolves when alert is found and verified. |
| 1607 | */ |
| 1608 | async waitForBrowserAlert({ text, windowTitle, timeout = this.timeout }) { |
| 1609 | const currentTitle = await this.driver.getTitle(); |
| 1610 | if (currentTitle === windowTitle) { |
| 1611 | await this.driver.wait(until.alertIsPresent(), timeout); |
| 1612 | const alert = await this.driver.switchTo().alert(); |
| 1613 | const alertText = await alert.getText(); |
| 1614 | |
| 1615 | if (alertText !== text) { |
| 1616 | throw new Error( |
| 1617 | `Expected alert text to be "${text}", but got "${alertText}".`, |
| 1618 | ); |
| 1619 | } |
| 1620 | } else { |
| 1621 | await this.driver.wait(async () => { |
| 1622 | try { |
| 1623 | await this.switchToWindowWithTitle(windowTitle); |
| 1624 | // If window switch succeeds, alert hasn't appeared yet - keep waiting |
| 1625 | return false; |
| 1626 | } catch (error) { |
| 1627 | if ( |
| 1628 | error.name === 'UnexpectedAlertOpenError' || |
| 1629 | (error.message && |
| 1630 | error.message.includes('unexpected alert open')) || |
| 1631 | (error.message && |
| 1632 | error.message.includes('Unexpected alert dialog detected')) |
| 1633 | ) { |
| 1634 | if (process.env.SELENIUM_BROWSER === Browser.FIREFOX) { |
| 1635 | // Firefox doesn't include alert text in error message |
| 1636 | try { |
| 1637 | const alert = await this.driver.switchTo().alert(); |
| 1638 | const alertText = await alert.getText(); |
| 1639 | if (alertText !== text) { |
| 1640 | throw new Error( |
| 1641 | `Expected alert text to be "${text}", but got "${alertText}".`, |
| 1642 | ); |
| 1643 | } |
| 1644 | return true; |
| 1645 | } catch (alertError) { |
| 1646 | console.warn( |
| 1647 | `Could not access alert directly. Expected: "${text}". Error: ${alertError.message}`, |
| 1648 | ); |
| 1649 | return true; |
| 1650 | } |
| 1651 | } else { |
| 1652 | const alertTextMatch = error.message.match( |
| 1653 | /Alert text\s*:\s*(.+?)(?:\s*\}|$)/u, |
| 1654 | ); |
| 1655 | if (alertTextMatch) { |
| 1656 | const alertText = alertTextMatch[1].trim(); |
| 1657 | if (alertText !== text) { |
| 1658 | throw new Error( |
| 1659 | `Expected alert text to be "${text}", but got "${alertText}".`, |
| 1660 | ); |
| 1661 | } |
| 1662 | return true; |
| 1663 | } |
| 1664 | throw new Error( |
| 1665 | `Could not extract alert text from UnexpectedAlertOpenError. Full error message: "${error.message}"`, |
no test coverage detected