Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
Revert of Revert of Add support for codepen to form_based_credentials…
Browse files Browse the repository at this point in the history
…_background (patchset #9 of https://codereview.chromium.org/485743002/)

Reason for revert:
I believe the flakiness may have been fixed by https://codereview.chromium.org/520683002

BUG=

Review URL: https://codereview.chromium.org/531733004

Cr-Commit-Position: refs/heads/master@{#292950}
  • Loading branch information
anniesullie authored and Commit bot committed Sep 2, 2014
1 parent afba614 commit dab69c8
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 54 deletions.
2 changes: 1 addition & 1 deletion tools/perf/page_sets/data/credentials.json.sha1
Original file line number Diff line number Diff line change
@@ -1 +1 @@
11752daf3b27c9ced2d530b5241cab7e5b109dd9
3a0f9c995a41e058857af7d9c2e265b046ba96e6
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from telemetry.core.backends import form_based_credentials_backend


class CodePenCredentialsBackend(
form_based_credentials_backend.FormBasedCredentialsBackend):

@property
def logged_in_javascript(self):
"""Evaluates to true iff already logged in."""
return 'document.querySelector(".login-area") === null'

@property
def credentials_type(self):
return 'codepen'

@property
def url(self):
return 'https://codepen.io/login'

@property
def login_form_id(self):
return 'login-login-form'

@property
def login_button_javascript(self):
return """
LoginSettings.timeOnPageStartTime = 0;
document.getElementById("log-in-button").click();
"""

@property
def login_input_id(self):
return 'login-email-field'

@property
def password_input_id(self):
return 'login-password-field_'
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from telemetry.core.backends import form_based_credentials_backend_unittest_base
from telemetry.core.backends import codepen_credentials_backend


class TestCodePenCredentialsBackend(
form_based_credentials_backend_unittest_base.
FormBasedCredentialsBackendUnitTestBase):
def setUp(self):
self._credentials_type = 'codepen'

def testLoginUsingMock(self):
backend = codepen_credentials_backend.CodePenCredentialsBackend()
self._LoginUsingMock(backend, backend.url, backend.login_input_id,
backend.password_input_id, backend.login_form_id,
backend.logged_in_javascript)
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@

class FacebookCredentialsBackend(
form_based_credentials_backend.FormBasedCredentialsBackend):
def IsAlreadyLoggedIn(self, tab):
return tab.EvaluateJavaScript(
'document.getElementById("fbNotificationsList")!== null || '
'document.getElementById("m_home_notice")!== null')

@property
def logged_in_javascript(self):
"""Evaluates to true iff already logged in."""
return ('document.getElementById("fbNotificationsList")!== null || '
'document.getElementById("m_home_notice")!== null')

@property
def credentials_type(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def setUp(self):
self._credentials_type = 'facebook'

def testLoginUsingMock(self):
self._LoginUsingMock(
facebook_credentials_backend.FacebookCredentialsBackend(),
'http://www.facebook.com/', 'email', 'pass')
backend = facebook_credentials_backend.FacebookCredentialsBackend()
self._LoginUsingMock(backend, backend.url, backend.login_input_id,
backend.password_input_id, backend.login_form_id,
backend.logged_in_javascript)
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,12 @@
from telemetry.core import util


def _WaitForLoginFormToLoad(backend, login_form_id, tab):
def IsFormLoadedOrAlreadyLoggedIn():
return (tab.EvaluateJavaScript(
'document.querySelector("#%s")!== null' % login_form_id) or
backend.IsAlreadyLoggedIn(tab))

# Wait until the form is submitted and the page completes loading.
util.WaitFor(IsFormLoadedOrAlreadyLoggedIn, 60)

def _SubmitFormAndWait(form_id, tab):
tab.ExecuteJavaScript(
'document.getElementById("%s").submit();' % form_id)

def FinishedLoading():
return not tab.EvaluateJavaScript(
'document.querySelector("#%s") !== null' % form_id)

# Wait until the form is submitted and the page completes loading.
util.WaitFor(FinishedLoading, 60)

class FormBasedCredentialsBackend(object):
def __init__(self):
self._logged_in = False

def IsAlreadyLoggedIn(self, tab):
raise NotImplementedError()
return tab.EvaluateJavaScript(self.logged_in_javascript)

@property
def credentials_type(self):
Expand All @@ -45,6 +25,11 @@ def url(self):
def login_form_id(self):
raise NotImplementedError()

@property
def login_button_javascript(self):
"""Some sites have custom JS to log in."""
return None

@property
def login_input_id(self):
raise NotImplementedError()
Expand All @@ -53,6 +38,11 @@ def login_input_id(self):
def password_input_id(self):
raise NotImplementedError()

@property
def logged_in_javascript(self):
"""Evaluates to true iff already logged in."""
raise NotImplementedError()

def IsLoggedIn(self):
return self._logged_in

Expand All @@ -62,7 +52,31 @@ def _ResetLoggedInState(self):
"""
self._logged_in = False

def LoginNeeded(self, tab, config):
def _WaitForLoginState(self, action_runner):
"""Waits until it can detect either the login form, or already logged in."""
condition = '(document.querySelector("#%s") !== null) || (%s)' % (
self.login_form_id, self.logged_in_javascript)
action_runner.WaitForJavaScriptCondition(condition, 60)

def _SubmitLoginFormAndWait(self, action_runner, tab, username, password):
"""Submits the login form and waits for the navigation."""
tab.WaitForDocumentReadyStateToBeInteractiveOrBetter()
email_id = 'document.querySelector("#%s #%s").value = "%s"; ' % (
self.login_form_id, self.login_input_id, username)
password = 'document.querySelector("#%s #%s").value = "%s"; ' % (
self.login_form_id, self.password_input_id, password)
tab.ExecuteJavaScript(email_id)
tab.ExecuteJavaScript(password)
if self.login_button_javascript:
tab.ExecuteJavaScript(self.login_button_javascript)
else:
tab.ExecuteJavaScript(
'document.getElementById("%s").submit();' % self.login_form_id)
# Wait for the form element to disappear as confirmation of the navigation.
action_runner.WaitForNavigate()


def LoginNeeded(self, tab, action_runner, config):
"""Logs in to a test account.
Raises:
Expand All @@ -86,23 +100,14 @@ def LoginNeeded(self, tab, config):
try:
logging.info('Loading %s...', url)
tab.Navigate(url)
_WaitForLoginFormToLoad(self, self.login_form_id, tab)
self._WaitForLoginState(action_runner)

if self.IsAlreadyLoggedIn(tab):
self._logged_in = True
return True

tab.WaitForDocumentReadyStateToBeInteractiveOrBetter()
logging.info('Loaded page: %s', url)

email_id = 'document.querySelector("#%s").%s.value = "%s"; ' % (
self.login_form_id, self.login_input_id, config['username'])
password = 'document.querySelector("#%s").%s.value = "%s"; ' % (
self.login_form_id, self.password_input_id, config['password'])
tab.ExecuteJavaScript(email_id)
tab.ExecuteJavaScript(password)

_SubmitFormAndWait(self.login_form_id, tab)
self._SubmitLoginFormAndWait(
action_runner, tab, config['username'], config['password'])

self._logged_in = True
return True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,23 @@ def testLoginUsingMock(self):
raise NotImplementedError()

def _LoginUsingMock(self, backend, login_page_url, email_element_id,
password_element_id): # pylint: disable=R0201
password_element_id, form_element_id,
already_logged_in_js): # pylint: disable=R0201
tab = simple_mock.MockObject()
ar = simple_mock.MockObject()

config = {'username': 'blah',
'password': 'blargh'}

tab.ExpectCall('Navigate', login_page_url)
tab.ExpectCall('EvaluateJavaScript', _).WillReturn(False)
tab.ExpectCall('EvaluateJavaScript', _).WillReturn(True)
tab.ExpectCall('EvaluateJavaScript', _).WillReturn(False)
tab.ExpectCall('EvaluateJavaScript', already_logged_in_js).WillReturn(False)
tab.ExpectCall('WaitForDocumentReadyStateToBeInteractiveOrBetter')

ar.ExpectCall('WaitForJavaScriptCondition',
'(document.querySelector("#%s") !== null) || (%s)' % (
form_element_id, already_logged_in_js), 60)
ar.ExpectCall('WaitForNavigate')

def VerifyEmail(js):
assert email_element_id in js
assert 'blah' in js
Expand All @@ -118,10 +123,10 @@ def VerifyPw(js):
tab.ExpectCall('ExecuteJavaScript', _).WhenCalled(VerifyPw)

def VerifySubmit(js):
assert '.submit' in js
assert '.submit' in js or '.click' in js
tab.ExpectCall('ExecuteJavaScript', _).WhenCalled(VerifySubmit)

# Checking for form still up.
tab.ExpectCall('EvaluateJavaScript', _).WillReturn(False)

backend.LoginNeeded(tab, config)
backend.LoginNeeded(tab, ar, config)
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@

class GoogleCredentialsBackend(
form_based_credentials_backend.FormBasedCredentialsBackend):
def IsAlreadyLoggedIn(self, tab):
return tab.EvaluateJavaScript(
'document.getElementById("gb")!== null')

@property
def logged_in_javascript(self):
"""Evaluates to true iff already logged in."""
return 'document.getElementById("gb")!== null'

@property
def credentials_type(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ def setUp(self):
def testLoginUsingMock(self):
backend = google_credentials_backend.GoogleCredentialsBackend()
self._LoginUsingMock(backend, backend.url, backend.login_input_id,
backend.password_input_id)
backend.password_input_id, backend.login_form_id,
backend.logged_in_javascript)
6 changes: 5 additions & 1 deletion tools/telemetry/telemetry/core/browser_credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
import os

from telemetry.core import util
from telemetry.core.backends import codepen_credentials_backend
from telemetry.core.backends import facebook_credentials_backend
from telemetry.core.backends import google_credentials_backend
from telemetry.page.actions import action_runner
from telemetry.unittest import options_for_unittests


Expand All @@ -24,6 +26,7 @@ def __init__(self, backends = None):

if backends is None:
backends = [
codepen_credentials_backend.CodePenCredentialsBackend(),
facebook_credentials_backend.FacebookCredentialsBackend(),
google_credentials_backend.GoogleCredentialsBackend()]

Expand Down Expand Up @@ -55,8 +58,9 @@ def LoginNeeded(self, tab, credentials_type):
'Unrecognized credentials type: %s', credentials_type)
if credentials_type not in self._credentials:
return False
runner = action_runner.ActionRunner(tab)
return self._backends[credentials_type].LoginNeeded(
tab, self._credentials[credentials_type])
tab, runner, self._credentials[credentials_type])

def LoginNoLongerNeeded(self, tab, credentials_type):
assert credentials_type in self._backends
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def __init__(self, credentials_type):
self.login_no_longer_needed_called = None
self.credentials_type = credentials_type

def LoginNeeded(self, config, tab):
def LoginNeeded(self, config, _, tab):
self.login_needed_called = (config, tab)
return True

Expand Down

0 comments on commit dab69c8

Please sign in to comment.