コード例 #1
0
def _load_family(driver: Remote, url: str) -> Bundle:
    builder = Bundle.builder()

    driver.get(url)

    # todo: compare with store currency
    currency = driver.execute_script("return Currency.currentCurrency;")

    meta = driver.execute_script("return window.ShopifyAnalytics.meta;")
    element = driver.find_element_by_id("product-form-{}".format(
        meta["page"]["resourceId"]))

    family_json = ujson.loads(element.get_attribute("data-product"))
    family = _new_family(url, family_json)
    builder.family(family)

    for product_json in family_json["variants"]:
        product = _new_product(family.id, product_json)
        builder.product(product)

        image_json = product_json["featured_image"]
        if image_json:
            builder.image(_new_product_image(family.id, product.id,
                                             image_json))

    bundle = builder.build()

    logger.debug(
        "Loaded product family '%s' with %d products and %d images from '%s'",
        bundle.family.name, len(bundle.products), len(bundle.images),
        bundle.family.url)

    return bundle
コード例 #2
0
def create_window(browser: webdriver.Remote) -> webdriver.Remote:
    windows_before = browser.window_handles
    browser.execute_script("window.open('');")

    WebDriverWait(browser, 10).until(
        EC.number_of_windows_to_be(len(windows_before) + 1)
    )

    windows_after = browser.window_handles
    new_windows = set(windows_after) - set(windows_before)
    browser.switch_to.window(new_windows.pop())
    return browser
コード例 #3
0
def navigate(driver: Remote):
    """
    目的のページに遷移する。
    """
    logging.info('Navigating...')
    driver.get('https://note.mu/')  # noteのトップページを開く。
    assert 'note' in driver.title  # タイトルに'note'が含まれていることを確認する。

    # 3回繰り返す。
    for _ in range(3):
        # ページの一番下までスクロールする。
        driver.execute_script('scroll(0, document.body.scrollHeight)')
        logging.info('Waiting for contents to be loaded...')
        time.sleep(2)  # 2秒間待つ。
コード例 #4
0
ファイル: applicant.py プロジェクト: parkun-by/appeal_sender
    def attach_photos(self, photo_paths: list,
                      browser: webdriver.Remote) -> None:
        attach_field = self._get_element_by_xpath("//input[@type=\"file\"]",
                                                  browser)

        label = attach_field.find_element_by_xpath("./..")

        js = "arguments[0].style.height='100px'; \
            arguments[0].style.width='100px'; \
            arguments[0].style.overflow='visible'; \
            arguments[0].style.visibility='visible'; \
            arguments[0].style.opacity = 1"

        browser.execute_script(js, label)

        for path in photo_paths:
            try:
                self._fill_field(attach_field, path)
            except Exception as exc:
                logger.info(f'Фотка не прикрепляется {path} - {str(exc)}')

        logger.info("Прикрепили файлы")
コード例 #5
0
def navigate(driver: Remote):
    """
    目的のページに遷移する。
    """
    logging.info('Navigating...')
    driver.get('https://note.mu/')  # noteのトップページを開く。
    assert 'note' in driver.title  # タイトルに'note'が含まれていることを確認する。

    # 3回繰り返す。
    for _ in range(3):
        # 待つべき要素の番号(現在の要素数 + 10)を計算する。
        # 最初の2要素だけ親要素が異なるので、現在の要素数の計算からは除く。
        n = len(
            driver.find_elements_by_css_selector(
                '.o-timeline > div > .o-timeline__item')) + 10
        # ページの一番下までスクロールする。
        driver.execute_script('scroll(0, document.body.scrollHeight)')
        logging.info('Waiting for contents to be loaded...')
        # n番目のコンテンツに対応する要素が表示されるまで待つ。nth-of-type()の番号は1始まり。
        # タイムアウトは10秒で、10秒待っても表示されない場合は例外が発生する。
        WebDriverWait(driver, 10).until(
            EC.visibility_of_element_located(
                (By.CSS_SELECTOR, f'.o-timeline__item:nth-of-type({n})')))
コード例 #6
0
ファイル: applicant.py プロジェクト: parkun-by/appeal_sender
    def enter_appeal(self, xpath: str, appeal_text: str,
                     browser: webdriver.Remote):
        text_for_js = json.dumps(appeal_text, ensure_ascii=False)

        browser.execute_script(
            f'document.getElementById("input_20").value={text_for_js};')
コード例 #7
0
ファイル: applicant.py プロジェクト: parkun-by/appeal_sender
    def make_visible(self, element, browser: webdriver.Remote) -> None:
        # returns dict of X, Y coordinates
        coordinates = element.location_once_scrolled_into_view

        browser.execute_script(
            f'window.scrollTo({coordinates["x"]}, {coordinates["y"]});')
コード例 #8
0
ファイル: __init__.py プロジェクト: sky-uk/mite
class _SeleniumWrapper:
    def __init__(self, context):
        """Constructor pulls capabilities and other webdriver config from the context
        which should allow user to set whatever browser configuration that they want.
        Anything which needs a dictionary or object will be imported from a definition
        using a spec_import'"""
        self._context = context
        # Should only need the capabilities setting, other options for selenium experts
        self._command_executor = RemoteConnection(
            self._context.config.get("webdriver_command_executor",
                                     "http://127.0.0.1:4444/wd/hub"),
            resolve_ip=False,
        )
        self._keep_alive = self._context.config.get("webdriver_keep_alive",
                                                    False)
        self._file_detector = self._spec_import_if_not_none(
            "webdriver_file_detector")
        self._proxy = self._spec_import_if_not_none("webdriver_proxy")
        self._browser_profile = self._spec_import_if_not_none(
            "webdriver_browser_profile")
        self._options = self._spec_import_if_not_none("webdriver_options")

        # Required param
        self._capabilities = self._context.config.get("webdriver_capabilities")
        self._capabilities = spec_import(self._capabilities)

    def _spec_import_if_not_none(self, config_option):
        value = self._context.config.get(config_option, None)
        if value:
            value = spec_import(value)
        return value

    def _start(self):
        self._context.browser = self
        self._remote = SeleniumRemote(
            desired_capabilities=self._capabilities,
            command_executor=self._command_executor,
            browser_profile=self._browser_profile,
            proxy=self._proxy,
            keep_alive=self._keep_alive,
            file_detector=self._file_detector,
            options=self._options,
        )
        self._context.raw_webdriver = self._remote

    def _quit(self):
        if hasattr(self, "_remote"):
            self._remote.quit()

    def _browser_has_timing_capabilities(self):
        return self._remote.capabilities["browserName"] == "chrome"

    def _is_using_tls(self, name):
        return name.startswith("https")

    def _get_tls_timing(self, timings):
        if self._is_using_tls(timings["name"]):
            return timings["connectEnd"] - timings["secureConnectionStart"]
        else:
            logger.info(
                "Secure TLS connection not used, defaulting tls_time to 0")
            return 0

    def _get_tcp_timing(self, timings):
        if self._is_using_tls(timings["name"]):
            return timings["secureConnectionStart"] - timings["connectStart"]
        else:
            return timings["connectEnd"] - timings["connectStart"]

    def _send_page_load_metrics(self):
        if self._browser_has_timing_capabilities():
            performance_entries = self._remote.execute_script(
                "return performance.getEntriesByType('navigation')")

            paint_entries = self._remote.execute_script(
                "return performance.getEntriesByType('paint')")

            _timings = self._extract_entries(performance_entries)
            timings = _timings[0] if _timings else None
            if timings:
                protocol = timings.get("nextHopProtocol")
                if protocol != "http/1.1":
                    logger.warning(
                        f"Timings may be inaccurate as protocol is not http/1.1: {protocol}"
                    )
                metrics = {
                    "dns_lookup_time":
                    timings["domainLookupEnd"] - timings["domainLookupStart"],
                    "dom_interactive":
                    timings["domInteractive"],
                    "js_onload_time":
                    timings["domContentLoadedEventEnd"] -
                    timings["domContentLoadedEventStart"],
                    "page_weight":
                    timings["transferSize"],
                    "render_time":
                    timings["domInteractive"] - timings["responseEnd"],
                    "tcp_time":
                    self._get_tcp_timing(timings),
                    "time_to_first_byte":
                    timings["responseStart"] - timings["connectEnd"],
                    "time_to_interactive":
                    timings["domInteractive"] - timings["requestStart"],
                    "time_to_last_byte":
                    timings["responseEnd"] - timings["connectEnd"],
                    "tls_time":
                    self._get_tls_timing(timings),
                    "total_time":
                    timings["duration"],
                }
            else:
                metrics = {}

            _paint_timings = self._extract_entries(paint_entries, expected=2)
            paint_timings = (self._format_paint_timings(_paint_timings)
                             if _paint_timings else None)
            if paint_timings:
                metrics["first_contentful_paint"] = paint_timings[
                    "first-contentful-paint"]
                metrics["first_paint"] = paint_timings["first-paint"]

            if metrics:
                self._context.send(
                    "selenium_page_load_metrics",
                    **self._extract_and_convert_metrics_to_seconds(metrics),
                )

    def _extract_entries(self, entries, expected=1):
        if len(entries) != expected:
            logger.error(
                f"Performance entries did not return the expected count: expected 1 - actual {len(entries)}"
            )
            return
        else:
            return entries[:expected]

    def _format_paint_timings(self, entries):
        return {metric["name"]: metric["startTime"] for metric in entries}

    def _extract_and_convert_metrics_to_seconds(self, metrics):
        converted_metrics = dict()
        non_time_based_metrics = ["page_weight", "resource_path"]
        for k, v in metrics.items():
            if k not in non_time_based_metrics:
                converted_metrics[k] = self._convert_ms_to_seconds(v)
            else:
                converted_metrics[k] = v
        return converted_metrics

    def _convert_ms_to_seconds(self, value_ms):
        return value_ms / 1000

    def _retrieve_javascript_metrics(self):
        try:
            return self._remote.execute_script(
                "return performance.getEntriesByType('resource')")
        except Exception:
            logger.error("Failed to retrieve resource performance entries")
            return []

    def _clear_resource_timings(self):
        self._remote.execute_script("performance.clearResourceTimings()")

    def get(self, url):
        self._remote.get(url)
        self._send_page_load_metrics()

    def get_js_metrics_context(self):
        return JsMetricsContext(self)

    def wait_for_elements(self, locator, timeout=5):
        return self._wait_for(
            EC.presence_of_all_elements_located,
            locator,
            f"Timed out trying to find elements '{locator}' in the dom",
            timeout,
        )

    def wait_for_element(self, locator, timeout=5):
        return self._wait_for(
            EC.presence_of_element_located,
            locator,
            f"Timed out trying to find element '{locator}' in the dom",
            timeout,
        )

    def wait_for_url(self, locator, timeout=5):
        return self._wait_for(
            EC.url_to_be,
            locator,
            f"Timed out waiting for url to be '{locator}' in the dom",
            timeout,
        )

    def _wait_for(self, condition_func, locator, err_msg, timeout=5):
        try:
            return WebDriverWait(self._remote,
                                 timeout).until(condition_func(locator))
        except TimeoutException as te:
            raise MiteError(err_msg) from te

    def switch_to_default(self):
        self._remote.switch_to.default_content()

    def switch_to_iframe(self, locator):
        self._remote.switch_to.frame(self._remote.find_element(*locator))

    def switch_to_parent(self):
        self._remote.switch_to.parent_frame()

    @property
    def current_url(self):
        return self._remote.current_url
コード例 #9
0
ファイル: BasePage.py プロジェクト: zhaowen13/ui
class BasePage(object):
    def __init__(self, project_name):
        self.driver = ''
        self.loc = ''
        self.project_name = project_name
        yamlPath = "user.yaml"
        yaml.load(yamlPath, Loader=yaml.BaseLoader)
        yaml.warnings({'YAMLLoadWarning': False})
        f = open(yamlPath, 'r')
        temp = yaml.load(f.read())
        self.url = temp[project_name]['url']
        self.username = temp[project_name]['username']
        self.password = temp[project_name]['password']

    def open(self,
             browser="chrome",
             host='http://localhost:8081/wd/hub'
             ):  # 初始化 打开浏览器 并最大化  self 与java中的this中一样,调用时不用传入self参数
        try:
            self.driver = Remote(command_executor=host,
                                 desired_capabilities={
                                     'platform': 'ANY',
                                     'browserName': browser,
                                     'version': '',
                                     'javascriptEnabled': True
                                 })
            self.driver.maximize_window()
        except Exception as e:
            print(e)

        logger_cls.info(u"打开{0}浏览器".format(browser))
        logger_cls.info(u"最大化")

    def get(self):
        try:
            self.driver.get(self.url)
            self.driver.implicitly_wait(10)  # 隐性等待,最长等10秒
            logger_cls.info(u'打开:{0}'.format(self.url))
        except BaseException:
            logger_cls.error(u'打开{0}失败'.format(self.url))
        self.loc = loc.Analyze(self.project_name)  #初始化,读取xml 赋值给loc

    def find(self, name):  #元素定位,并返回定位好的元素
        try:
            el = WebDriverWait(self.driver, 3,
                               0.5).until(  #设置显示等待时间,每0.5秒检查一次,如果超出指定值就报错
                                   EC.presence_of_element_located(
                                       (self.loc[name].type,
                                        self.loc[name].UIIdentifier)))
            logger_cls.info(u'定位元素:{0}'.format(name))
            # logger_cls.info(loc[name].value)
        except BaseException:
            logger_cls.error(u'定位元素:{0}失败'.format(name))
        return el

    def send_keys(self, name, text):
        try:
            self.find(name).send_keys(text)
            logger_cls.info(u'在:{0}输入{1}'.format(name, text))
            time.sleep(3)
        except BaseException:
            logger_cls.error(u'在:{0}输入{1}失败'.format(name, text))

    def click(self, name):
        try:
            self.find(name).click()
            logger_cls.info(u'点击:{0}'.format(name))
            time.sleep(3)
        except BaseException:
            logger_cls.error(u'点击:{0}失败'.format(name))

    def being(self, name):
        t = False
        try:
            self.driver.find_element_by_xpath(self.loc[name].UIIdentifier)
            t = True
            logger_cls.info(u'{0}元素存在'.format(name))
        except BaseException:
            logger_cls.info(u'{0}元素不存在'.format(name))
        return t

    def login(self):
        self.get()
        self.send_keys(u'用户名', self.username)
        self.send_keys(u'密码', self.password)
        self.click(u'登录')
        time.sleep(3)
        if self.being(u'不再提示'):
            self.click(u'不再提示')
        # self.get_version()

    def clearmonitor(self):
        names = [u'博主', u'博主圈']
        self.click(u'事件')
        if self.being(u'是否有事件'):
            self.focus(u'找回')
            self.click(u'多选')
            self.click(u'全选')
            self.click(u'删除')
        for name in names:
            self.click(name)
            if self.being(u'是否有博主'):
                self.focus(u'找回')
                self.click(u'多选')
                self.click(u'全选')
                self.click(u'删除')

    def randomclick(self, name, div=None):
        text = ''
        i = len(self.driver.find_elements_by_xpath(
            self.loc[name].UIIdentifier))
        logger_cls.info(u'{0}列表中有{1}个参数'.format(name, i))
        y = random.randint(1, i)
        if div == None:
            path = self.loc[name].UIIdentifier + '[' + str(y) + ']'
            text = self.driver.find_element_by_xpath(path).text
            self.driver.find_element_by_xpath(path).click()
            logger_cls.info(u'随机选择列表中的{0}第个参数并点击'.format(y))
        else:
            i2 = len(
                self.driver.find_elements_by_xpath(
                    self.loc[name].UIIdentifier + '[' + str(y) + ']'))
            y2 = random.randint(1, i2)
            path = self.loc[name].UIIdentifier + '[' + str(y2) + ']' + div
            text = self.driver.find_element_by_xpath(path).text
            self.driver.find_element_by_xpath(path).click()
            logger_cls.info(u'随机选择列表中的{0}第个参数并点击'.format(y2))

        logger_cls.info(u'{0}:文本的值为:{1}'.format(name, text))
        time.sleep(3)
        return text

    def close(self):
        logger_cls.info(u'3秒后关闭当前页面')
        time.sleep(3)
        self.driver.close()

    def quit(self):
        logger_cls.info(u'3秒后关闭浏览器')
        time.sleep(3)
        self.driver.quit()

    def get_url(self):
        url = self.driver.current_url
        logger_cls.info(u'当前页面url:' + url)
        return url

    def get_text(self, name):
        text = self.find(name).text
        logger_cls.info(u'{0}文本框的值为:{1}'.format(name, text))
        return text

    def back(self):
        self.driver.back()
        logger_cls.info(u'返回上一页面')

    def clear(self, name):
        self.find(name).clear()
        logger_cls.info(u'清空文本框:{0}'.format(name))

    def get_name(self):
        name = self.driver.name
        logger_cls.info(u'浏览器名称:{0}'.format(name))

    def get_driver(self):
        return self.driver

    def get_version(self):
        version = self.driver.capabilities['version']
        logger_cls.info(u'浏览器版本:{0}'.format(version))
        return version

    def switch_to(self):
        self.driver.switch_to.window(self.driver.window_handles[-1])
        logger_cls.info(u'切换页面')

    def focus(self, name):
        ele = self.find(name)
        ActionChains(self.driver).move_to_element(ele).perform()
        logger_cls.info(u'鼠标悬停到元素:{0}'.format(name))

    def refresh(self):
        self.driver.refresh()
        logger_cls.info(u'刷新页面')

    def title(self):
        title = self.driver.title
        logger_cls.info(u'当前页面标题' + title)
        return title

    def Slide(self, height):
        js = "var q=document.documentElement.scrollTop={0}".format(str(height))
        self.driver.execute_script(js)
        logger_cls.info(u'上下滑动' + str(height))

    def sleep(self, i):
        logger_cls.info(u'暂停{0}秒'.format(i))
        time.sleep(int(i))

    def Screenshot(self, name):
        # name='screenshot_'
        isExists = os.path.exists("../images\\")
        # 判断结果
        if not isExists:
            # 如果不存在则创建目录
            # 创建目录操作函数
            os.makedirs("../images\\")
            print u'创建images目录'
        timestrmap = time.strftime('%Y%m%d_%H%M%S')
        imgPath = os.path.join('../images\\', str(timestrmap) + name + '.png')
        self.driver.save_screenshot(imgPath)
        logger_cls.info(u'截图:{0}{1}.png'.format(str(timestrmap), name))
コード例 #10
0
ファイル: browser.py プロジェクト: ralfeus/order
class Browser:
    __AWAIT_TIMEOUT = 60
    __browser = None
    __browser_kwargs = {}
    __config = {}
    __refs_num = 0

    def get_browser(self):
        return self.__browser

    def __init__(self, headless=True, config={}, **kwargs):
        self.__config = config
        self.__config['SELENIUM_HEADLESS'] = headless
        self.__browser_kwargs = kwargs
        if self.__config.get('SELENIUM_URL'):
            self.__create_browser_session()
        else:
            self.__create_browser_instanse()

    def __del__(self):
        if self.__browser:
            self.__browser.quit()
            logging.debug("%s: Quitted browser at __del__()",
                          self.__config['CELERY_TASK_DEFAULT_QUEUE'])
            del self.__browser

    def __create_browser_instanse(self):
        options = Options()
        if self.__config.get('SELENIUM_HEADLESS'):
            options.headless = True
        if self.__config.get('SELENIUM_BROWSER'):
            options.add_experimental_option("debuggerAddress",
                                            self.__config['SELENIUM_BROWSER'])
        if self.__config.get('SELENIUM_DRIVER'):
            self.__browser_kwargs['executable_path'] = self.__config[
                'SELENIUM_DRIVER']
        if self.__config.get(
                'LOG_LEVEL') and self.__config['LOG_LEVEL'] == logging.DEBUG:
            if self.__config.get('SELENIUM_LOG_PATH'):
                self.__browser_kwargs['service_log_path'] = self.__config[
                    'SELENIUM_LOG_PATH']
            self.__browser_kwargs['service_args'] = ['--verbose']

        if not self.__browser_kwargs.get('executable_path'):
            self.__browser_kwargs['executable_path'] = '/usr/bin/chromedriver'
        self.__browser = Chrome(options=options, **self.__browser_kwargs)
        logging.debug("%s: Created browser instance",
                      self.__config['CELERY_TASK_DEFAULT_QUEUE'])

    def __create_browser_session(self):
        options = Options()
        if self.__config.get('SELENIUM_HEADLESS'):
            options.headless = True
        self.__browser = Remote(command_executor=self.__config['SELENIUM_URL'],
                                options=options)
        logging.debug("Connected to remote browser")

    def __get_by(self, criterium, value):
        ignored_exceptions = (
            NoSuchElementException,
            StaleElementReferenceException,
        )
        try:
            return WebDriverWait(self.__browser,
                                 self.__AWAIT_TIMEOUT,
                                 ignored_exceptions=ignored_exceptions).until(
                                     EC.presence_of_element_located(
                                         (criterium, value)))
        except UnexpectedAlertPresentException as ex:
            raise ex
        except TimeoutException as ex:
            raise NoSuchElementException(
                f"No element with {criterium} {value} was found", ex)

    def click_by_id(self, element_id):
        self.__browser.execute_script(f'$("#{element_id}").click()')

    def doubleclick(self, element):
        ActionChains(self.__browser).double_click(element).perform()

    def execute_script(self, script, *args):
        return self.__browser.execute_script(script, *args)

    def dismiss_alert(self):
        try:
            self.__browser.switch_to_alert().dismiss()
        except NoAlertPresentException:
            pass

    def find_element_by_xpath(self, xpath):
        return self.__browser.find_element_by_xpath(xpath)

    def find_elements_by_xpath(self, xpath):
        return self.__browser.find_elements_by_xpath(xpath)

    def find_elements_by_css_selector(self, css):
        return self.__browser.find_elements_by_css_selector(css)

    def get(self, url):
        exception = None
        for attempt in range(3):
            try:
                self.__browser.get(url)
                exception = None
                break
            except Exception as ex:
                self.quit()
                self.__create_browser_instanse()
                exception = ex
        if exception:
            raise exception

    def get_alert(self):
        try:
            alert = self.__browser.switch_to_alert()
            text = alert.text
            alert.dismiss()
            return text
        except NoAlertPresentException:
            return None

    def get_element_by_class(self, class_name):
        return self.__get_by(By.CLASS_NAME, class_name)

    def get_element_by_css(self, css):
        return self.__get_by(By.CSS_SELECTOR, css)

    def get_element_by_id(self, id):
        return self.__get_by(By.ID, id)

    def get_element_by_name(self, name):
        return self.__get_by(By.NAME, name)

    def switch_to_alert(self):
        return self.__browser.switch_to.alert

    def wait_for_url(self, url):
        try:
            WebDriverWait(self.__browser, 20).until(EC.url_to_be(url))
        except UnexpectedAlertPresentException as ex:
            raise UnexpectedAlertPresentException(ex.alert_text,
                                                  f"Didn't get URL {url}")
        except Exception as ex:
            raise Exception(f"Didn't get URL {url}", ex)

    def close(self):
        self.__browser.get('about:blank')

    def quit(self):
        if self.__browser:
            self.__browser.quit()
            logging.debug("%s: Quitted browser at quit()",
                          self.__config['CELERY_TASK_DEFAULT_QUEUE'])
            del self.__browser

    @property
    def title(self):
        return self.__browser.title
コード例 #11
0
def scroll_to_view(remote: webdriver.Remote, *args):
    remote.execute_script("arguments[0].scrollIntoView(true);", *args)
コード例 #12
0
ファイル: browser.py プロジェクト: shoptime/trex
class Browser(object):
    def __init__(self, harness, selenium_server_url, selenium_browser, width=1024, height=600):
        self.harness = harness
        self.selenium_server_url = selenium_server_url
        self.selenium_browser = selenium_browser
        self.width = width
        self.height = height

        self.selenium = Remote(
            self.selenium_server_url.encode('ascii'),
            desired_capabilities = {
                'browserName': self.selenium_browser,
            },
        )
        self.selenium.set_window_size(width, height)

    def __enter__(self):
        self.harness.browser_stack.append(self)
        return self

    def __exit__(self, type, value, traceback):
        if self.harness.browser_stack[-1] != self:
            raise Exception("Unexpected browser on the top of the stack")
        self.harness.browser_stack.pop()
        return

    def shutdown(self):
        self.selenium.quit()

    def back(self):
        self.selenium.back()

    def refresh(self):
        self.selenium.refresh()

    def title(self):
        return self.selenium.title

    def source(self):
        return self.selenium.page_source

    def get(self, uri):
        self.selenium.get(uri)

    def find(self, selector):
        return WebElementSet(self, elements=self.selenium).find(selector)

    def add_cookie(self, cookie_dict):
        self.selenium.add_cookie(cookie_dict)

    def get_cookie(self, name):
        return self.selenium.get_cookie(name)

    def endpoint(self):
        return self.find('html').attr('id').replace('endpoint-', '').replace('-', '.')

    def endpoint_is(self, endpoint):
        is_equal(self.endpoint(), endpoint, "Endpoint is correct")

    def wait_for_bootstrap_modal(self):
        last = [None]

        def inner_wait(driver):
            value = self.find('.modal')[-1].css('top')
            if last[0] and last[0] == value:
                return True
            last[0] = value
            return False
        WebDriverWait(self.selenium, 3).until(inner_wait)
        return self

    def url(self):
        return furl(self.selenium.current_url)

    def execute_script(self, script):
        return self.selenium.execute_script(script)

    def wait_for_ajax(self):
        WebDriverWait(self.selenium, 10).until_not(lambda x: x.execute_script('return jQuery.active'))
        return self

    def wait_for_jquery(self):
        WebDriverWait(self.selenium, 10).until(lambda x: x.execute_script('return window.jQuery ? true : false'))
        return self

    def screenshot(self, message="Screenshot: "):
        if 's3_access_key' not in app.settings.options('test'):
            print "No screenshot S3 instance configured - skipping screenshot"
            return

        if not hasattr(self, 's3_connection'):
            if 's3_host' in app.settings.options('test'):
                self.s3_connection = boto.s3.connection.S3Connection(
                    app.settings.get('test', 's3_access_key'),
                    app.settings.get('test', 's3_secret_key'),
                    host = app.settings.get('test', 's3_host'),
                )
            else:
                self.s3_connection = boto.s3.connection.S3Connection(
                    app.settings.get('test', 's3_access_key'),
                    app.settings.get('test', 's3_secret_key'),
                )

        bucket = self.s3_connection.get_bucket(app.settings.get('test', 's3_bucket'))
        filename = "%s-%s.png" % (token.create_url_token(), self.harness.current_test_object.__class__.__name__)

        key = bucket.new_key(filename)
        key.metadata['Content-Type'] = 'image/png'
        key.metadata['Cache-Control'] = 'public, max-age=86400'
        key.set_contents_from_string(self.selenium.get_screenshot_as_png())
        key.make_public()
        print "%s%s" % (message, key.generate_url(expires_in=0, query_auth=False))
コード例 #13
0
ファイル: tests.py プロジェクト: santiycr/django
class AdminSeleniumWebDriverTestCase(LiveServerTestCase):

    available_apps = [
        "django.contrib.admin",
        "django.contrib.auth",
        "django.contrib.contenttypes",
        "django.contrib.sessions",
        "django.contrib.sites",
    ]

    def _get_remote_capabilities(self, specs):
        platforms = {
            "s": "Windows 2008",
            "x": "Windows 2003",
            "e": "Windows 2012",
            "l": "Linux",
            "m": "Mac 10.6",
            "i": "Mac 10.8",
        }
        browsers = {
            "ff": "firefox",
            "op": "opera",
            "ie": "internet explorer",
            "sa": "safari",
            "ip": "ipad",
            "ih": "iphone",
            "an": "android",
            "gc": "chrome",
        }
        browser = browsers[specs[:2]]
        if specs[-1] in platforms:
            platform = platforms.get(specs[-1])
            version = specs[2:-1]
        else:
            platform = None
            version = specs[2:]
        caps = {"browserName": browser, "version": version, "platform": platform, "public": "public"}
        if "BUILD_NUMBER" in os.environ:
            caps["build"] = os.environ["BUILD_NUMBER"]
        elif "TRAVIS_BUILD_NUMBER" in os.environ:
            caps["build"] = os.environ["TRAVIS_BUILD_NUMBER"]
        return caps

    def _get_local_webdriver_class(self, specs):
        browsers = {
            "ff": "selenium.webdriver.Firefox",
            "op": "selenium.webdriver.Opera",
            "ie": "selenium.webdriver.Ie",
            "gc": "selenium.webdriver.Chrome",
        }
        return import_by_path(browsers[specs[:2]])

    def setUp(self):
        test_method = getattr(self, self._testMethodName)
        if not hasattr(test_method, "spec"):
            raise SkipTest("Please make sure your test class is decorated with @browserize")
        elif not test_method.spec:
            raise SkipTest("Selenium tests not requested")
        try:
            selenium_specs = test_method.spec
            if os.environ.get("DJANGO_SELENIUM_REMOTE", False):
                webdriver_class = import_by_path("selenium.webdriver.Remote")
            else:
                webdriver_class = self._get_local_webdriver_class(selenium_specs)
        except Exception as e:
            raise SkipTest(
                'Selenium specifications "%s" not valid or '
                "corresponding WebDriver not installed: %s" % (selenium_specs, str(e))
            )

        from selenium.webdriver import Remote

        if webdriver_class is Remote:
            if not (os.environ.get("REMOTE_USER") and os.environ.get("REMOTE_KEY")):
                raise self.failureException(
                    "Both REMOTE_USER and REMOTE_KEY environment variables are required for remote tests."
                )
            capabilities = self._get_remote_capabilities(selenium_specs)
            capabilities["name"] = self.id()
            auth = "%(REMOTE_USER)s:%(REMOTE_KEY)s" % os.environ
            hub = os.environ.get("REMOTE_HUB", "ondemand.saucelabs.com:80")
            self.selenium = Remote(
                command_executor="http://%s@%s/wd/hub" % (auth, hub), desired_capabilities=capabilities
            )
        else:
            self.selenium = webdriver_class()

        super(AdminSeleniumWebDriverTestCase, self).setUp()

    def tearDown(self):
        if hasattr(self, "selenium"):
            from selenium.webdriver import Remote

            if isinstance(self.selenium, Remote):
                self._report_sauce_pass_fail()
            self.selenium.quit()
        super(AdminSeleniumWebDriverTestCase, self).tearDown()

    def _report_sauce_pass_fail(self):
        # Sauce Labs has no way of knowing if the test passed or failed, so we
        # let it know.
        base64string = base64.encodestring("%s:%s" % (os.environ.get("REMOTE_USER"), os.environ.get("REMOTE_KEY")))[:-1]
        result = json.dumps({"passed": sys.exc_info() == (None, None, None)})
        url = "/rest/v1/%s/jobs/%s" % (os.environ.get("REMOTE_USER"), self.selenium.session_id)
        connection = httplib.HTTPConnection("saucelabs.com")
        connection.request("PUT", url, result, headers={"Authorization": "Basic %s" % base64string})
        result = connection.getresponse()
        return result.status == 200

    def wait_until(self, callback, timeout=10):
        """
        Helper function that blocks the execution of the tests until the
        specified callback returns a value that is not falsy. This function can
        be called, for example, after clicking a link or submitting a form.
        See the other public methods that call this function for more details.
        """
        from selenium.webdriver.support.wait import WebDriverWait

        WebDriverWait(self.selenium, timeout).until(callback)

    def wait_loaded_tag(self, tag_name, timeout=10):
        """
        Helper function that blocks until the element with the given tag name
        is found on the page.
        """
        self.wait_until(lambda driver: driver.find_element_by_tag_name(tag_name), timeout)

    def wait_page_loaded(self):
        """
        Block until page has started to load.
        """
        from selenium.common.exceptions import TimeoutException

        try:
            # Wait for the next page to be loaded
            self.wait_loaded_tag("body")
        except TimeoutException:
            # IE7 occasionnally returns an error "Internet Explorer cannot
            # display the webpage" and doesn't load the next page. We just
            # ignore it.
            pass

    def admin_login(self, username, password, login_url="/admin/"):
        """
        Helper function to log into the admin.
        """
        self.selenium.get("%s%s" % (self.live_server_url, login_url))
        username_input = self.selenium.find_element_by_name("username")
        username_input.send_keys(username)
        password_input = self.selenium.find_element_by_name("password")
        password_input.send_keys(password)
        login_text = _("Log in")
        self.selenium.find_element_by_xpath('//input[@value="%s"]' % login_text).click()
        self.wait_page_loaded()

    def get_css_value(self, selector, attribute):
        """
        Helper function that returns the value for the CSS attribute of an
        DOM element specified by the given selector. Uses the jQuery that ships
        with Django.
        """
        return self.selenium.execute_script('return django.jQuery("%s").css("%s")' % (selector, attribute))

    def get_select_option(self, selector, value):
        """
        Returns the <OPTION> with the value `value` inside the <SELECT> widget
        identified by the CSS selector `selector`.
        """
        from selenium.common.exceptions import NoSuchElementException

        options = self.selenium.find_elements_by_css_selector("%s > option" % selector)
        for option in options:
            if option.get_attribute("value") == value:
                return option
        raise NoSuchElementException('Option "%s" not found in "%s"' % (value, selector))

    def assertSelectOptions(self, selector, values):
        """
        Asserts that the <SELECT> widget identified by `selector` has the
        options with the given `values`.
        """
        options = self.selenium.find_elements_by_css_selector("%s > option" % selector)
        actual_values = []
        for option in options:
            actual_values.append(option.get_attribute("value"))
        self.assertEqual(values, actual_values)

    def has_css_class(self, selector, klass):
        """
        Returns True if the element identified by `selector` has the CSS class
        `klass`.
        """
        return self.selenium.find_element_by_css_selector(selector).get_attribute("class").find(klass) != -1