From 695a85313ce2cb32f6b7f91333c3da9b2e27fca5 Mon Sep 17 00:00:00 2001 From: Dave Hunt Date: Wed, 1 Feb 2012 23:19:15 +0000 Subject: [PATCH] Initial commit. --- .gitignore | 2 ++ browser_id.py | 23 +++++++++++++ pages/__init__.py | 0 pages/rc/__init__.py | 0 pages/rc/base.py | 46 ++++++++++++++++++++++++++ pages/rc/sign_in.py | 64 +++++++++++++++++++++++++++++++++++++ pages/webdriver/__init__.py | 0 pages/webdriver/base.py | 25 +++++++++++++++ pages/webdriver/sign_in.py | 63 ++++++++++++++++++++++++++++++++++++ tests/__init__.py | 0 tests/test_sign_in.py | 48 ++++++++++++++++++++++++++++ 11 files changed, 271 insertions(+) create mode 100644 .gitignore create mode 100644 browser_id.py create mode 100644 pages/__init__.py create mode 100644 pages/rc/__init__.py create mode 100644 pages/rc/base.py create mode 100644 pages/rc/sign_in.py create mode 100644 pages/webdriver/__init__.py create mode 100644 pages/webdriver/base.py create mode 100644 pages/webdriver/sign_in.py create mode 100644 tests/__init__.py create mode 100644 tests/test_sign_in.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1cf12dd --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.pyc +*.komodoproject diff --git a/browser_id.py b/browser_id.py new file mode 100644 index 0000000..0e41ef8 --- /dev/null +++ b/browser_id.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import selenium + + +class BrowserID(object): + + def __init__(self, selenium, timeout=60): + self.selenium = selenium + self.timeout = timeout + + def sign_in(self, email, password): + """Signs in using the specified email address and password.""" + if isinstance(self.selenium, selenium.selenium): + from pages.rc.sign_in import SignIn + else: + from pages.webdriver.sign_in import SignIn + sign_in = SignIn(self.selenium, timeout=self.timeout) + sign_in.sign_in(email, password) diff --git a/pages/__init__.py b/pages/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pages/rc/__init__.py b/pages/rc/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pages/rc/base.py b/pages/rc/base.py new file mode 100644 index 0000000..2125971 --- /dev/null +++ b/pages/rc/base.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python + +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import time + +from selenium.webdriver.common.by import By + + +class Base(object): + + _page_title = 'Browser ID' + + def __init__(self, selenium, timeout=60): + self.selenium = selenium + self.timeout = timeout + if selenium.get_title != self._page_title: + self.wait_for_popup() + selenium.select_pop_up(self._page_title) + + def wait_for_popup(self): + count = 0 + while not self._page_title in self.selenium.get_all_window_titles(): + time.sleep(1) + count += 1 + if count == self.timeout: + raise Exception('Popup has not loaded') + + def wait_for_element_present(self, element): + count = 0 + while not self.selenium.is_element_present(element): + time.sleep(1) + count += 1 + if count == self.timeout: + raise Exception(element + ' has not loaded') + + def wait_for_element_visible(self, element): + self.wait_for_element_present(element) + count = 0 + while not self.selenium.is_visible(element): + time.sleep(1) + count += 1 + if count == self.timeout: + raise Exception(element + ' is not visible') diff --git a/pages/rc/sign_in.py b/pages/rc/sign_in.py new file mode 100644 index 0000000..b887a41 --- /dev/null +++ b/pages/rc/sign_in.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python + +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +from base import Base + + +class SignIn(Base): + + _email_locator = 'id=email' + _password_locator = 'id=password' + _next_locator = 'css=button.start' + _select_email_locator = 'css=button.returning' + _sign_in_locator = 'id=signInButton' + + @property + def email(self): + """Get the value of the email field.""" + self.wait_for_element_visible(self._email_locator) + return self.selenium.get_text(self._email_locator) + + @email.setter + def email(self, value): + """Set the value of the email field.""" + self.wait_for_element_visible(self._email_locator) + self.selenium.type(self._email_locator, value) + + @property + def password(self): + """Get the value of the password field.""" + self.wait_for_element_visible(self._password_locator) + return self.selenium.get_text(self._password_locator) + + @password.setter + def password(self, value): + """Set the value of the password field.""" + self.wait_for_element_visible(self._password_locator) + self.selenium.type(self._password_locator, value) + + def click_next(self): + """Clicks the 'next' button.""" + self.wait_for_element_visible(self._next_locator) + self.selenium.click(self._next_locator) + + def click_select_email(self): + """Clicks the 'select email' button.""" + self.wait_for_element_visible(self._select_email_locator) + self.selenium.click(self._select_email_locator) + + def click_sign_in(self): + """Clicks the 'Sign In' button.""" + self.wait_for_element_visible(self._sign_in_locator) + self.selenium.click(self._sign_in_locator) + self.selenium.deselect_pop_up() + + def sign_in(self, email, password): + """Signs in using the specified email address and password.""" + self.email = email + self.click_next() + self.password = password + self.click_select_email() + self.click_sign_in() diff --git a/pages/webdriver/__init__.py b/pages/webdriver/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pages/webdriver/base.py b/pages/webdriver/base.py new file mode 100644 index 0000000..e54ffe4 --- /dev/null +++ b/pages/webdriver/base.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +from selenium.webdriver.support.ui import WebDriverWait + + +class Base(object): + + _page_title = 'Browser ID' + + def __init__(self, selenium, timeout=60): + self.selenium = selenium + self.timeout = timeout + if selenium.title != self._page_title: + for handle in selenium.window_handles: + selenium.switch_to_window(handle) + if selenium.title == self._page_title: + break + + def wait_for_element_displayed(self, locator): + WebDriverWait(self.selenium, self.timeout).until(lambda s: s.find_element(*locator).is_displayed()) + return self.selenium.find_element(*locator) diff --git a/pages/webdriver/sign_in.py b/pages/webdriver/sign_in.py new file mode 100644 index 0000000..218925e --- /dev/null +++ b/pages/webdriver/sign_in.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python + +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +from base import Base + +from selenium.webdriver.common.by import By + + +class SignIn(Base): + + _email_locator = (By.ID, 'email') + _password_locator = (By.ID, 'password') + _next_locator = (By.CSS_SELECTOR, 'button.start') + _select_email_locator = (By.CSS_SELECTOR, 'button.returning') + _sign_in_locator = (By.ID, 'signInButton') + + @property + def email(self): + """Get the value of the email field.""" + return self.wait_for_element_displayed(self._email_locator).text + + @email.setter + def email(self, value): + """Set the value of the email field.""" + email = self.wait_for_element_displayed(self._email_locator) + email.clear() + email.send_keys(value) + + @property + def password(self): + """Get the value of the password field.""" + return self.wait_for_element_displayed(self._password_locator).text + + @password.setter + def password(self, value): + """Set the value of the password field.""" + password = self.wait_for_element_displayed(self._password_locator) + password.clear() + password.send_keys(value) + + def click_next(self): + """Clicks the 'next' button.""" + self.wait_for_element_displayed(self._next_locator).click() + + def click_select_email(self): + """Clicks the 'select email' button.""" + self.wait_for_element_displayed(self._select_email_locator).click() + + def click_sign_in(self): + """Clicks the 'Sign In' button.""" + self.wait_for_element_displayed(self._sign_in_locator).click() + self.selenium.switch_to_window('') + + def sign_in(self, email, password): + """Signs in using the specified email address and password.""" + self.email = email + self.click_next() + self.password = password + self.click_select_email() + self.click_sign_in() diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_sign_in.py b/tests/test_sign_in.py new file mode 100644 index 0000000..cd4faad --- /dev/null +++ b/tests/test_sign_in.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python + +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import time + +from browser_id import BrowserID + +from selenium import webdriver +from selenium import selenium + +class TestSignIn: + + _email = '' + _password = '' + + def test_sign_in_to_my_favorite_beer_using_webdriver(self): + sel = webdriver.Firefox() + sel.implicitly_wait(10) + sel.get('http://myfavoritebeer.org/') + sel.find_element_by_css_selector('#loginInfo .login').click() + + # BrowserID + browser_id = BrowserID(sel) + browser_id.sign_in(self._email, self._password) + + assert sel.find_element_by_id('logout').is_displayed + sel.quit() + + def test_sign_in_to_my_favorite_beer_using_rc(self): + sel = selenium('localhost', '4444', '*firefox', 'http://myfavoritebeer.org') + sel.start() + sel.open('/') + sel.click('css=#loginInfo .login') + + # BrowserID + browser_id = BrowserID(sel) + browser_id.sign_in(self._email, self._password) + + logout_locator = 'id=logout' + count = 0 + while count < 60 and not (sel.is_element_present(logout_locator) and sel.is_visible(logout_locator)): + time.sleep(1) + count += 1 + assert sel.is_visible('id=logout') + sel.stop()