• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2013 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4import logging
5
6from telemetry.core import util
7
8
9def _WaitForLoginFormToLoad(backend, login_form_id, tab):
10  def IsFormLoadedOrAlreadyLoggedIn():
11    return (tab.EvaluateJavaScript(
12        'document.querySelector("#%s")!== null' % login_form_id) or
13            backend.IsAlreadyLoggedIn(tab))
14
15  # Wait until the form is submitted and the page completes loading.
16  util.WaitFor(IsFormLoadedOrAlreadyLoggedIn, 60)
17
18def _SubmitFormAndWait(form_id, tab):
19  tab.ExecuteJavaScript(
20      'document.getElementById("%s").submit();' % form_id)
21
22  def FinishedLoading():
23    return not tab.EvaluateJavaScript(
24        'document.querySelector("#%s") !== null' % form_id)
25
26  # Wait until the form is submitted and the page completes loading.
27  util.WaitFor(FinishedLoading, 60)
28
29class FormBasedCredentialsBackend(object):
30  def __init__(self):
31    self._logged_in = False
32
33  def IsAlreadyLoggedIn(self, tab):
34    raise NotImplementedError()
35
36  @property
37  def credentials_type(self):
38    raise NotImplementedError()
39
40  @property
41  def url(self):
42    raise NotImplementedError()
43
44  @property
45  def login_form_id(self):
46    raise NotImplementedError()
47
48  @property
49  def login_input_id(self):
50    raise NotImplementedError()
51
52  @property
53  def password_input_id(self):
54    raise NotImplementedError()
55
56  def IsLoggedIn(self):
57    return self._logged_in
58
59  def _ResetLoggedInState(self):
60    """Makes the backend think we're not logged in even though we are.
61    Should only be used in unit tests to simulate --dont-override-profile.
62    """
63    self._logged_in = False
64
65  def LoginNeeded(self, tab, config):
66    """Logs in to a test account.
67
68    Raises:
69      RuntimeError: if could not get credential information.
70    """
71    if self._logged_in:
72      return True
73
74    if 'username' not in config or 'password' not in config:
75      message = ('Credentials for "%s" must include username and password.' %
76                 self.credentials_type)
77      raise RuntimeError(message)
78
79    logging.debug('Logging into %s account...' % self.credentials_type)
80
81    if 'url' in config:
82      url = config['url']
83    else:
84      url = self.url
85
86    try:
87      logging.info('Loading %s...', url)
88      tab.Navigate(url)
89      _WaitForLoginFormToLoad(self, self.login_form_id, tab)
90
91      if self.IsAlreadyLoggedIn(tab):
92        self._logged_in = True
93        return True
94
95      tab.WaitForDocumentReadyStateToBeInteractiveOrBetter()
96      logging.info('Loaded page: %s', url)
97
98      email_id = 'document.querySelector("#%s").%s.value = "%s"; ' % (
99          self.login_form_id, self.login_input_id, config['username'])
100      password = 'document.querySelector("#%s").%s.value = "%s"; ' % (
101          self.login_form_id, self.password_input_id, config['password'])
102      tab.ExecuteJavaScript(email_id)
103      tab.ExecuteJavaScript(password)
104
105      _SubmitFormAndWait(self.login_form_id, tab)
106
107      self._logged_in = True
108      return True
109    except util.TimeoutException:
110      logging.warning('Timed out while loading: %s', url)
111      return False
112
113  def LoginNoLongerNeeded(self, tab): # pylint: disable=W0613
114    assert self._logged_in
115