• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2024 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5from __future__ import annotations
6
7from typing import TYPE_CHECKING
8
9from crossbench.benchmarks.loading.config.login.base import PresetLoginBlock
10from crossbench.cli.config.secret_type import SecretType
11
12if TYPE_CHECKING:
13  from crossbench.action_runner.base import ActionRunner
14  from crossbench.benchmarks.loading.page.interactive import InteractivePage
15  from crossbench.cli.config.secrets import Secret
16  from crossbench.runner.actions import Actions
17  from crossbench.runner.run import Run
18
19GOOGLE_LOGIN_URL: str = (
20    "https://accounts.google.com/Logout?"
21    "continue=https%3A%2F%2Faccounts.google.com%2Fv3%2Fsignin%2Fidentifier%3F"
22    "flowName%3DGlifWebSignIn%26flowEntry%3DServiceLogin")
23
24TRUSTED_EMAIL_CHECK: str = (
25    "return document.getElementById('verifycontactNext') != null")
26
27
28class GoogleLogin(PresetLoginBlock):
29  """Google-specific login steps."""
30
31  def _submit_login_field(self, action: Actions, aria_label: str,
32                          input_val: str, button_name: str) -> None:
33    action.wait_js_condition(
34        ("return "
35         f"document.querySelector(\"[aria-label='{aria_label}']\") != null &&"
36         f"document.getElementById({repr(button_name)}) != null;"), 0.2, 10)
37    action.js("const inputField ="
38              f" document.querySelector(\"[aria-label='{aria_label}']\");"
39              f"inputField.value = {repr(input_val)};"
40              f"document.getElementById({repr(button_name)}).click();")
41
42  def run_with(self, runner: ActionRunner, run: Run,
43               page: InteractivePage) -> None:
44    secret: Secret = self.get_secret(run, page, SecretType.GOOGLE)
45
46    if self.is_logged_in(run, secret, strict=True):
47      return
48
49    with run.actions("Login", measure=False) as action:
50      action.show_url(GOOGLE_LOGIN_URL)
51      self._submit_login_field(action, "Email or phone", secret.username,
52                               "identifierNext")
53      action.wait_js_condition(
54          "return document.getElementById('verifycontactNext') || "
55          "document.getElementById('passwordNext') != null;", 0.2, 10)
56      if action.js(TRUSTED_EMAIL_CHECK):
57        self._test_account_login(action, secret)
58      else:
59        self._standard_login(action, secret)
60
61  def _standard_login(self, action, secret):
62    self._submit_login_field(action, "Enter your password", secret.password,
63                             "passwordNext")
64    action.wait_js_condition(
65        "return document.URL.startsWith('https://myaccount.google.com');", 0.2,
66        10)
67
68  def _test_account_login(self, action, secret):
69    self._submit_login_field(action, "Enter trusted contact\\’s email",
70                             secret.password, "verifycontactNext")
71    # TODO: handle account passkey setup, for now each test account needs a
72    # one time manual interaction.
73    action.wait_js_condition(
74        "return document.URL.startsWith('https://myaccount.google.com')", 0.2,
75        60)
76