1# Copyright 2014 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
5from functools import partial
6import logging
7
8from telemetry.core import exceptions
9from telemetry.core import util
10from telemetry.internal.browser import web_contents
11
12
13class Oobe(web_contents.WebContents):
14  def __init__(self, inspector_backend):
15    super(Oobe, self).__init__(inspector_backend)
16
17  def _GaiaIFrameContext(self):
18    max_context_id = self.EnableAllContexts()
19    logging.debug('%d contexts in Gaia page' % max_context_id)
20    for gaia_iframe_context in range(max_context_id + 1):
21      try:
22        if self.EvaluateJavaScriptInContext(
23            "document.readyState == 'complete' && "
24            "document.getElementById('Email') != null",
25            gaia_iframe_context):
26          return gaia_iframe_context
27      except exceptions.EvaluateException:
28        pass
29    return None
30
31  def _GaiaWebviewContext(self):
32    webview_contexts = self.GetWebviewContexts()
33    if webview_contexts:
34      return webview_contexts[0]
35    return None
36
37  def _ExecuteOobeApi(self, api, *args):
38    logging.info('Invoking %s' % api)
39    self.WaitForJavaScriptExpression("typeof Oobe == 'function'", 20)
40
41    if self.EvaluateJavaScript("typeof %s == 'undefined'" % api):
42      raise exceptions.LoginException('%s js api missing' % api)
43
44    js = api + '(' + ("'%s'," * len(args)).rstrip(',') + ');'
45    self.ExecuteJavaScript(js % args)
46
47  def NavigateGuestLogin(self):
48    """Logs in as guest."""
49    self._ExecuteOobeApi('Oobe.guestLoginForTesting')
50
51  def NavigateFakeLogin(self, username, password, gaia_id):
52    """Fake user login."""
53    self._ExecuteOobeApi('Oobe.loginForTesting', username, password, gaia_id)
54
55  def NavigateGaiaLogin(self, username, password,
56                        enterprise_enroll=False,
57                        for_user_triggered_enrollment=False):
58    """Logs in using the GAIA webview or IFrame, whichever is
59    present. |enterprise_enroll| allows for enterprise enrollment.
60    |for_user_triggered_enrollment| should be False for remora enrollment."""
61    self._ExecuteOobeApi('Oobe.skipToLoginForTesting')
62    if for_user_triggered_enrollment:
63      self._ExecuteOobeApi('Oobe.switchToEnterpriseEnrollmentForTesting')
64
65    self._NavigateGaiaLogin(username, password, enterprise_enroll)
66
67    if enterprise_enroll:
68      self.WaitForJavaScriptExpression('Oobe.isEnrollmentSuccessfulForTest()',
69                                       30)
70      self._ExecuteOobeApi('Oobe.enterpriseEnrollmentDone')
71
72  def _NavigateGaiaLogin(self, username, password, enterprise_enroll):
73    """Invokes NavigateIFrameLogin or NavigateWebViewLogin as appropriate."""
74    def _GetGaiaFunction():
75      if self._GaiaWebviewContext() is not None:
76        return partial(Oobe._NavigateWebViewLogin,
77                       wait_for_close=not enterprise_enroll)
78      elif self._GaiaIFrameContext() is not None:
79        return partial(Oobe._NavigateIFrameLogin,
80                       add_user_for_testing=not enterprise_enroll)
81      return None
82    util.WaitFor(_GetGaiaFunction, 20)(self, username, password)
83
84  def _NavigateIFrameLogin(self, username, password, add_user_for_testing):
85    """Logs into the IFrame-based GAIA screen"""
86    gaia_iframe_context = util.WaitFor(self._GaiaIFrameContext, timeout=30)
87
88    if add_user_for_testing:
89      self._ExecuteOobeApi('Oobe.showAddUserForTesting')
90    self.ExecuteJavaScriptInContext("""
91        document.getElementById('Email').value='%s';
92        document.getElementById('Passwd').value='%s';
93        document.getElementById('signIn').click();"""
94            % (username, password),
95        gaia_iframe_context)
96
97  def _NavigateWebViewLogin(self, username, password, wait_for_close):
98    """Logs into the webview-based GAIA screen"""
99    self._NavigateWebViewEntry('identifierId', username, 'identifierNext')
100    self._NavigateWebViewEntry('password', password, 'next')
101    if wait_for_close:
102      util.WaitFor(lambda: not self._GaiaWebviewContext(), 20)
103
104  def _NavigateWebViewEntry(self, field, value, nextField):
105    self._WaitForField(field)
106    self._WaitForField(nextField)
107    gaia_webview_context = self._GaiaWebviewContext()
108    gaia_webview_context.EvaluateJavaScript("""
109       document.getElementById('%s').value='%s';
110       document.getElementById('%s').click()"""
111           % (field, value, nextField))
112
113  def _WaitForField(self, field_id):
114    gaia_webview_context = util.WaitFor(self._GaiaWebviewContext, 5)
115    util.WaitFor(gaia_webview_context.HasReachedQuiescence, 20)
116    gaia_webview_context.WaitForJavaScriptExpression(
117        "document.getElementById('%s') != null" % field_id, 20)
118