|
43 | 43 | from selenium.common.exceptions import WebDriverException |
44 | 44 | from selenium.webdriver.common.bidi.script import Script |
45 | 45 | from selenium.webdriver.common.by import By |
| 46 | +from selenium.webdriver.common.options import ArgOptions |
46 | 47 | from selenium.webdriver.common.options import BaseOptions |
47 | 48 | from selenium.webdriver.common.print_page_options import PrintOptions |
48 | 49 | from selenium.webdriver.common.timeouts import Timeouts |
|
53 | 54 | ) |
54 | 55 | from selenium.webdriver.support.relative_locator import RelativeBy |
55 | 56 |
|
| 57 | +from ..common.fedcm.dialog import Dialog |
56 | 58 | from .bidi_connection import BidiConnection |
57 | 59 | from .client_config import ClientConfig |
58 | 60 | from .command import Command |
@@ -1245,3 +1247,90 @@ def fedcm(self) -> FedCM: |
1245 | 1247 | driver.fedcm.reset_cooldown() |
1246 | 1248 | """ |
1247 | 1249 | return self._fedcm |
| 1250 | + |
| 1251 | + @property |
| 1252 | + def supports_fedcm(self) -> bool: |
| 1253 | + """Returns whether the browser supports FedCM capabilities.""" |
| 1254 | + return self.capabilities.get(ArgOptions.FEDCM_CAPABILITY, False) |
| 1255 | + |
| 1256 | + def _require_fedcm_support(self): |
| 1257 | + """Raises an exception if FedCM is not supported.""" |
| 1258 | + if not self.supports_fedcm: |
| 1259 | + raise WebDriverException( |
| 1260 | + "This browser does not support Federated Credential Management. " |
| 1261 | + "Please ensure you're using a supported browser." |
| 1262 | + ) |
| 1263 | + |
| 1264 | + @property |
| 1265 | + def dialog(self): |
| 1266 | + """Returns the FedCM dialog object for interaction.""" |
| 1267 | + self._require_fedcm_support() |
| 1268 | + return Dialog(self) |
| 1269 | + |
| 1270 | + def enable_fedcm_delay(self): |
| 1271 | + """Enables the promise rejection delay for FedCM. |
| 1272 | +
|
| 1273 | + Raises: |
| 1274 | + WebDriverException if FedCM not supported |
| 1275 | + """ |
| 1276 | + self._require_fedcm_support() |
| 1277 | + self.fedcm.enable_delay() |
| 1278 | + |
| 1279 | + def disable_fedcm_delay(self): |
| 1280 | + """Disables the promise rejection delay for FedCM. |
| 1281 | +
|
| 1282 | + FedCM by default delays promise resolution in failure cases for |
| 1283 | + privacy reasons. This method allows turning it off to let tests |
| 1284 | + run faster where this is not relevant. |
| 1285 | +
|
| 1286 | + Raises: |
| 1287 | + WebDriverException if FedCM not supported |
| 1288 | + """ |
| 1289 | + self._require_fedcm_support() |
| 1290 | + self.fedcm.disable_delay() |
| 1291 | + |
| 1292 | + def reset_fedcm_cooldown(self): |
| 1293 | + """Resets the FedCM dialog cooldown. |
| 1294 | +
|
| 1295 | + If a user agent triggers a cooldown when the account chooser is |
| 1296 | + dismissed, this method resets that cooldown so that the dialog |
| 1297 | + can be triggered again immediately. |
| 1298 | +
|
| 1299 | + Raises: |
| 1300 | + WebDriverException if FedCM not supported |
| 1301 | + """ |
| 1302 | + self._require_fedcm_support() |
| 1303 | + self.fedcm.reset_cooldown() |
| 1304 | + |
| 1305 | + def fedcm_dialog(self, timeout=5, poll_frequency=0.5, ignored_exceptions=None): |
| 1306 | + """Waits for and returns the FedCM dialog. |
| 1307 | +
|
| 1308 | + Args: |
| 1309 | + timeout: How long to wait for the dialog |
| 1310 | + poll_frequency: How frequently to poll |
| 1311 | + ignored_exceptions: Exceptions to ignore while waiting |
| 1312 | +
|
| 1313 | + Returns: |
| 1314 | + The FedCM dialog object if found |
| 1315 | +
|
| 1316 | + Raises: |
| 1317 | + TimeoutException if dialog doesn't appear |
| 1318 | + WebDriverException if FedCM not supported |
| 1319 | + """ |
| 1320 | + from selenium.common.exceptions import NoAlertPresentException |
| 1321 | + from selenium.webdriver.support.wait import WebDriverWait |
| 1322 | + |
| 1323 | + self._require_fedcm_support() |
| 1324 | + |
| 1325 | + if ignored_exceptions is None: |
| 1326 | + ignored_exceptions = (NoAlertPresentException,) |
| 1327 | + |
| 1328 | + def _check_fedcm(): |
| 1329 | + try: |
| 1330 | + dialog = Dialog(self) |
| 1331 | + return dialog if dialog.type else None |
| 1332 | + except NoAlertPresentException: |
| 1333 | + return None |
| 1334 | + |
| 1335 | + wait = WebDriverWait(self, timeout, poll_frequency=poll_frequency, ignored_exceptions=ignored_exceptions) |
| 1336 | + return wait.until(lambda _: _check_fedcm()) |
0 commit comments