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.
4
5import logging
6import os
7import unittest
8
9from telemetry import benchmark
10from telemetry.core import browser_finder
11from telemetry.core import util
12from telemetry.unittest import options_for_unittests
13from telemetry.unittest import simple_mock
14
15_ = simple_mock.DONT_CARE
16
17
18def _GetCredentialsPath():
19  # TODO: This shouldn't depend on tools/perf.
20  credentials_path = os.path.join(util.GetChromiumSrcDir(),
21      'tools', 'perf', 'data', 'credentials.json')
22  if not os.path.exists(credentials_path):
23    return None
24  return credentials_path
25
26
27class FormBasedCredentialsBackendUnitTestBase(unittest.TestCase):
28  def setUp(self):
29    self._credentials_type = None
30
31  @benchmark.Disabled
32  def testRealLoginIfPossible(self):
33    credentials_path = _GetCredentialsPath()
34    if not credentials_path:
35      logging.warning('Credentials file not found, skipping test.')
36      return
37
38    options = options_for_unittests.GetCopy()
39    with browser_finder.FindBrowser(options).Create() as b:
40      b.credentials.credentials_path = credentials_path
41      if not b.credentials.CanLogin(self._credentials_type):
42        return
43      ret = b.credentials.LoginNeeded(b.tabs[0], self._credentials_type)
44      self.assertTrue(ret)
45
46  @benchmark.Disabled
47  def testRealLoginWithDontOverrideProfileIfPossible(self):
48    credentials_path = _GetCredentialsPath()
49    if not credentials_path:
50      logging.warning('Credentials file not found, skipping test.')
51      return
52
53    options = options_for_unittests.GetCopy()
54
55    # Login once to make sure our default profile is logged in.
56    with browser_finder.FindBrowser(options).Create() as b:
57      b.credentials.credentials_path = credentials_path
58
59      if not b.credentials.CanLogin(self._credentials_type):
60        return
61
62      tab = b.tabs[0]
63
64      # Should not be logged in, since this is a fresh credentials
65      # instance.
66      self.assertFalse(b.credentials.IsLoggedIn(self._credentials_type))
67
68      # Log in.
69      ret = b.credentials.LoginNeeded(tab, self._credentials_type)
70
71      # Make sure login was successful.
72      self.assertTrue(ret)
73      self.assertTrue(b.credentials.IsLoggedIn(self._credentials_type))
74
75      # Reset state. Now the backend thinks we're logged out, even
76      # though we are logged in in our current browser session. This
77      # simulates the effects of running with --dont-override-profile.
78      b.credentials._ResetLoggedInState() # pylint: disable=W0212
79
80      # Make sure the backend thinks we're logged out.
81      self.assertFalse(b.credentials.IsLoggedIn(self._credentials_type))
82      self.assertTrue(b.credentials.CanLogin(self._credentials_type))
83
84      # Attempt to login again. This should detect that we've hit
85      # the 'logged in' page instead of the login form, and succeed
86      # instead of timing out.
87      ret = b.credentials.LoginNeeded(tab, self._credentials_type)
88
89      # Make sure our login attempt did in fact succeed and set the
90      # backend's internal state to 'logged in'.
91      self.assertTrue(ret)
92      self.assertTrue(b.credentials.IsLoggedIn(self._credentials_type))
93
94  def testLoginUsingMock(self):
95    raise NotImplementedError()
96
97  def _LoginUsingMock(self, backend, login_page_url, email_element_id,
98                      password_element_id, form_element_id,
99                      already_logged_in_js): # pylint: disable=R0201
100    tab = simple_mock.MockObject()
101    ar = simple_mock.MockObject()
102
103    config = {'username': 'blah',
104              'password': 'blargh'}
105
106    tab.ExpectCall('Navigate', login_page_url)
107    tab.ExpectCall('EvaluateJavaScript', already_logged_in_js).WillReturn(False)
108    tab.ExpectCall('WaitForDocumentReadyStateToBeInteractiveOrBetter')
109
110    ar.ExpectCall('WaitForJavaScriptCondition',
111                  '(document.querySelector("#%s") !== null) || (%s)' % (
112                      form_element_id, already_logged_in_js), 60)
113    ar.ExpectCall('WaitForNavigate')
114
115    def VerifyEmail(js):
116      assert email_element_id in js
117      assert 'blah' in js
118    tab.ExpectCall('ExecuteJavaScript', _).WhenCalled(VerifyEmail)
119
120    def VerifyPw(js):
121      assert password_element_id in js
122      assert 'largh' in js
123    tab.ExpectCall('ExecuteJavaScript', _).WhenCalled(VerifyPw)
124
125    def VerifySubmit(js):
126      assert '.submit' in js or '.click' in js
127    tab.ExpectCall('ExecuteJavaScript', _).WhenCalled(VerifySubmit)
128
129    # Checking for form still up.
130    tab.ExpectCall('EvaluateJavaScript', _).WillReturn(False)
131
132    backend.LoginNeeded(tab, ar, config)
133