diff --git a/saunter/_defaults/conftest.py b/saunter/_defaults/conftest.py index bc3dfe7..d68b52c 100644 --- a/saunter/_defaults/conftest.py +++ b/saunter/_defaults/conftest.py @@ -1,11 +1,11 @@ # Copyright 2011 Element 34 -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,7 +19,6 @@ import random import saunter.saucelabs - def pytest_configure(config): sys.path.append(os.path.join(os.getcwd(), "modules")) @@ -50,7 +49,8 @@ def pytest_runtest_makereport(__multicall__, item, call): if call.when == "call": if hasattr(item.parent.obj, 'config') and item.parent.obj.config["browsers"][item.parent.obj.config["saunter"]["default_browser"]]["sauce labs"]["ondemand"]: - s = saunter.saucelabs.SauceLabs(item) + s = saunter.saucelabs.SauceLabs(item.parent.obj.config["sauce labs"]["username"], item.parent.obj.config["sauce labs"]["key"]) + s.update_job_from_item(item) return report @@ -58,7 +58,8 @@ def pytest_runtest_teardown(__multicall__, item): __multicall__.execute() if hasattr(item.parent.obj, 'config') and item.parent.obj.config["browsers"][item.parent.obj.config["saunter"]["default_browser"]]["sauce labs"]["ondemand"]: - s = saunter.saucelabs.SauceLabs(item) + s = saunter.saucelabs.SauceLabs(item.parent.obj.config["sauce labs"]["username"], item.parent.obj.config["sauce labs"]["key"]) + s.update_job_from_item(item) def pytest_collection_modifyitems(items): random.shuffle(items) \ No newline at end of file diff --git a/saunter/browser.py b/saunter/browser.py new file mode 100644 index 0000000..ad6c69a --- /dev/null +++ b/saunter/browser.py @@ -0,0 +1,107 @@ +import sys +from tailored.webdriver import WebDriver as TailoredWebDriver +from saunter.exceptions import ProfileNotFound +from selenium.webdriver import FirefoxProfile +from selenium.webdriver.common.desired_capabilities import DesiredCapabilities +from saunter.matchers import Matchers + +capabilities_map = { + "firefox": DesiredCapabilities.FIREFOX, + "internet explorer": DesiredCapabilities.INTERNETEXPLORER, + "internetexplorer": DesiredCapabilities.INTERNETEXPLORER, + "iexplore": DesiredCapabilities.INTERNETEXPLORER, + "ie": DesiredCapabilities.INTERNETEXPLORER, + "chrome": DesiredCapabilities.CHROME, + "opera": DesiredCapabilities.OPERA, + "chrome": DesiredCapabilities.CHROME, + "htmlunitjs": DesiredCapabilities.HTMLUNITWITHJS, + "htmlunit": DesiredCapabilities.HTMLUNIT, + "iphone": DesiredCapabilities.IPHONE, + "ipad": DesiredCapabilities.IPAD, + "android": DesiredCapabilities.ANDROID, + "phantomjs": DesiredCapabilities.PHANTOMJS, +} + +os_map = { + "XP": "XP", + "Windows 2003": "XP", + "VISTA": "VISTA", + "Windows 2008": "VISTA", + "Linux": "LINUX", + "LINUX": "LINUX", + "MAC": "MAC" +} + +class Browser(TailoredWebDriver): + def __init__(self, browser_config, all_config): + self.browser_config = browser_config + self.config = all_config + + profile = None + if browser_config["type"] == 'firefox': + if browser_config["profiles"][sys.platform]: + profile_path = os.path.join(self.config["saunter"]["base"], 'support', 'profiles', browser_config["profiles"][sys.platform]) + elif browser_config["profiles"]["profile"]: + profile_path = os.path.join(self.config["saunter"]["base"], 'support', 'profiles', browser_config["profiles"]["profile"]) + else: + profile_path = None + + if profile_path: + if os.path.isdir(profile_path): + profile = FirefoxProfile(profile_path) + else: + raise ProfileNotFound("Profile not found at %s" % profile_path) + + if browser_config["sauce labs"]["ondemand"]: + desired_capabilities = { + "platform": browser_config["sauce labs"]["os"], + "browserName": browser_config["type"], + "version": browser_config["sauce labs"]["version"], + } + if desired_capabilities["platform"] in os_map: + desired_capabilities["platform"] = os_map[desired_capabilities["platform"]] + + if browser_config['sauce labs']['selenium version']: + desired_capabilities['selenium-version'] = browser['sauce labs']['selenium version'] + + if "disable" in self.config["sauce labs"] and self.config["sauce labs"]["disable"] is not None: + if "record video" in self.config["sauce labs"]["disable"]: + if self.config["sauce labs"]["disable"]["record video"] == True: + desired_capabilities['record-video'] = False + if "upload video on pass" in self.config["sauce labs"]["disable"]: + if self.config["sauce labs"]["disable"]["upload video on pass"] == True: + desired_capabilities['video-upload-on-pass'] = False + if "step screenshots" in self.config["sauce labs"]["disable"]: + if self.config["sauce labs"]["disable"]["step screenshots"] == True: + desired_capabilities['record-screenshots'] = False + if "sauce advisor" in self.config["sauce labs"]["disable"]: + if self.config["sauce labs"]["disable"]["sauce advisor"] == True: + desired_capabilities['sauce-advisor'] = False + + if "enable" in self.config["sauce labs"] and self.config["sauce labs"]["enable"] is not None: + if "source capture" in self.config["sauce labs"]["enable"]: + if self.config["sauce labs"]["enable"]["source capture"] == True: + desired_capabilities['source capture'] = True + if "error screenshots" in self.config["sauce labs"]["enable"]: + if self.config["sauce labs"]["enable"]["error screenshots"] == True: + desired_capabilities['webdriver.remote.quietExceptions'] = True + + command_executor = "http://%s:%s@ondemand.saucelabs.com:80/wd/hub" % (self.config["sauce labs"]["username"], self.config["sauce labs"]["key"]) + else: + desired_capabilities = capabilities_map[browser_config["type"]] + + if browser_config["proxy"]["type"] and browser_config["proxy"]["type"].lower() == "browsermob": + from browsermobproxy import Client + self.client = Client(self.config.get("Proxy", "proxy_url")) + self.client.add_to_webdriver_capabilities(desired_capabilities) + + if "is grid" in self.config["selenium"] and self.config["selenium"]["executor"]["is grid"]: + if browser_config["grid filters"]["platform"]: + desired_capabilities["platform"] = browser_config["grid filters"]["platform"].upper() + if browser_config["grid filters"]["version"]: + desired_capabilities["platform"] = str(browser_config["grid filters"]["version"]) + + command_executor = "http://%s:%s/wd/hub" % (self.config["selenium"]["executor"]["host"], self.config["selenium"]["executor"]["port"]) + + # print(desired_capabilities) + self.driver = TailoredWebDriver(desired_capabilities=desired_capabilities, command_executor=command_executor, browser_profile=profile) diff --git a/saunter/saucelabs.py b/saunter/saucelabs.py index 29b6c36..3b63296 100644 --- a/saunter/saucelabs.py +++ b/saunter/saucelabs.py @@ -6,14 +6,15 @@ class SauceLabs(object): - def __init__(self, item): + def __init__(self, username, key): + self.username = username + self.key = key + + def update_job_from_item(self, item): # session couldn't be established for some reason - if not hasattr(item.parent._obj, "sauce_session"): + if not hasattr(item.parent._obj.driver, "session_id"): return - self.sauce_session = item.parent._obj.sauce_session - self.username = item.parent._obj.config["sauce labs"]["username"] - self.key = item.parent._obj.config["sauce labs"]["key"] self.log_dir = item.parent._obj.config["saunter"]["log_dir"] j = {} @@ -58,7 +59,7 @@ def __init__(self, item): # print(json.dumps(j)) # update - which_url = "https://saucelabs.com/rest/v1/%s/jobs/%s" % (self.username, self.sauce_session) + which_url = "https://saucelabs.com/rest/v1/%s/jobs/%s" % (self.username, item.parent._obj.driver.session_id) r = requests.put(which_url, data=json.dumps(j), headers={"Content-Type": "application/json"}, @@ -87,3 +88,13 @@ def _fetch_sauce_artifact(self, which): artifact = open(os.path.join(self.log_dir, which), "wb") artifact.write(r.content) artifact.close() + + def update_name(self, session_id, name): + j = {"name": name} + + which_url = "https://saucelabs.com/rest/v1/%s/jobs/%s" % (self.username, session_id) + r = requests.put(which_url, + data=json.dumps(j), + headers={"Content-Type": "application/json"}, + auth=(self.username, self.key)) + r.raise_for_status() diff --git a/saunter/testcase/webdriver.py b/saunter/testcase/webdriver.py index ba48da1..30d16e2 100644 --- a/saunter/testcase/webdriver.py +++ b/saunter/testcase/webdriver.py @@ -25,12 +25,8 @@ import saunter.ConfigWrapper -try: - from tailored.webdriver import WebDriver -except ImportError as e: - if "DOCGENERATION" not in os.environ: - raise +import saunter.browser from selenium.webdriver.common.by import By from selenium.common.exceptions import WebDriverException from selenium.common.exceptions import TimeoutException @@ -41,37 +37,10 @@ from selenium.webdriver import FirefoxProfile import py.test from _pytest.mark import MarkInfo +import saunter.saucelabs from saunter.matchers import Matchers -capabilities_map = { - "firefox": DesiredCapabilities.FIREFOX, - "internet explorer": DesiredCapabilities.INTERNETEXPLORER, - "internetexplorer": DesiredCapabilities.INTERNETEXPLORER, - "iexplore": DesiredCapabilities.INTERNETEXPLORER, - "ie": DesiredCapabilities.INTERNETEXPLORER, - "chrome": DesiredCapabilities.CHROME, - "opera": DesiredCapabilities.OPERA, - "chrome": DesiredCapabilities.CHROME, - "htmlunitjs": DesiredCapabilities.HTMLUNITWITHJS, - "htmlunit": DesiredCapabilities.HTMLUNIT, - "iphone": DesiredCapabilities.IPHONE, - "ipad": DesiredCapabilities.IPAD, - "android": DesiredCapabilities.ANDROID, - "phantomjs": DesiredCapabilities.PHANTOMJS, -} - -os_map = { - "XP": "XP", - "Windows 2003": "XP", - "VISTA": "VISTA", - "Windows 2008": "VISTA", - "Linux": "LINUX", - "LINUX": "LINUX", - "MAC": "MAC" -} - - class SaunterTestCase(BaseTestCase): """ Parent class of all script classes used for custom asserts (usually 'soft' asserts) and shared fixture setup @@ -86,86 +55,17 @@ def setup_method(self, method): self.current_method_name = method.__name__ - browser = self.cf["browsers"][self.cf["saunter"]["default_browser"]] - if browser["type"][0] == "*": - browser = browser["type"] = browser["type"][1:] - - profile = None - if browser["type"] == 'firefox': - if browser["profiles"][sys.platform]: - profile_path = os.path.join(self.cf["saunter"]["base"], 'support', 'profiles', browser["profiles"][sys.platform]) - elif browser["profiles"]["profile"]: - profile_path = os.path.join(self.cf["saunter"]["base"], 'support', 'profiles', browser["profiles"]["profile"]) - else: - profile_path = None - - if profile_path: - if os.path.isdir(profile_path): - profile = FirefoxProfile(profile_path) - else: - raise ProfileNotFound("Profile not found at %s" % profile_path) - - if browser["sauce labs"]["ondemand"]: - desired_capabilities = { - "platform": browser["sauce labs"]["os"], - "browserName": browser["type"], - "version": browser["sauce labs"]["version"], - "name": method.__name__ - } - if desired_capabilities["platform"] in os_map: - desired_capabilities["platform"] = os_map[desired_capabilities["platform"]] - - if browser['sauce labs']['selenium version']: - desired_capabilities['selenium-version'] = browser['sauce labs']['selenium version'] - - if "disable" in self.cf["sauce labs"]: - if "record video" in self.cf["sauce labs"]["disable"]: - if self.cf["sauce labs"]["disable"]["record video"] == True: - desired_capabilities['record-video'] = False - if "upload video on pass" in self.cf["sauce labs"]["disable"]: - if self.cf["sauce labs"]["disable"]["upload video on pass"] == True: - desired_capabilities['video-upload-on-pass'] = False - if "step screenshots" in self.cf["sauce labs"]["disable"]: - if self.cf["sauce labs"]["disable"]["step screenshots"] == True: - desired_capabilities['record-screenshots'] = False - if "sauce advisor" in self.cf["sauce labs"]["disable"]: - if self.cf["sauce labs"]["disable"]["sauce advisor"] == True: - desired_capabilities['sauce-advisor'] = False - - if "enable" in self.cf["sauce labs"]: - if "source capture" in self.cf["sauce labs"]["enable"]: - if self.cf["sauce labs"]["enable"]["source capture"] == True: - desired_capabilities['source capture'] = True - if "error screenshots" in self.cf["sauce labs"]["enable"]: - if self.cf["sauce labs"]["enable"]["error screenshots"] == True: - desired_capabilities['webdriver.remote.quietExceptions'] = True - - command_executor = "http://%s:%s@ondemand.saucelabs.com:80/wd/hub" % (self.cf["sauce labs"]["username"], self.cf["sauce labs"]["key"]) - else: - desired_capabilities = capabilities_map[browser["type"]] - - if browser["proxy"]["type"] and browser["proxy"]["type"].lower() == "browsermob": - from browsermobproxy import Client - self.client = Client(self.cf.get("Proxy", "proxy_url")) - self.client.add_to_webdriver_capabilities(desired_capabilities) - - if "is grid" in self.cf["selenium"] and self.cf["selenium"]["executor"]["is grid"]: - if browser["grid filters"]["platform"]: - desired_capabilities["platform"] = browser["grid filters"]["platform"].upper() - if browser["grid filters"]["version"]: - desired_capabilities["platform"] = str(browser["grid filters"]["version"]) - - command_executor = "http://%s:%s/wd/hub" % (self.cf["selenium"]["executor"]["host"], self.cf["selenium"]["executor"]["port"]) - - # print(desired_capabilities) - self.driver = WebDriver(desired_capabilities=desired_capabilities, command_executor=command_executor, browser_profile=profile) + default_browser = self.cf["browsers"][self.cf["saunter"]["default_browser"]] + b = saunter.browser.Browser(default_browser, self.cf) + + self.driver = b.driver + if hasattr(self.driver, "session_id"): + s = saunter.saucelabs.SauceLabs(self.cf["sauce labs"]["username"], self.cf["sauce labs"]["key"]) + s.update_name(self.driver.session_id, self.current_method_name) self.verificationErrors = [] self.matchers = Matchers(self.driver, self.verificationErrors) - if browser["sauce labs"]["ondemand"]: - self.sauce_session = self.driver.session_id - self._screenshot_number = 1 def teardown_method(self, method):