<s> """<STR_LIT>""" <EOL> from abc import ABCMeta , abstractmethod , abstractproperty <EOL> from collections import defaultdict <EOL> from functools import wraps <EOL> from contextlib import contextmanager <EOL> import logging <EOL> import os <EOL> import socket <EOL> import urlparse <EOL> import re <EOL> from textwrap import dedent <EOL> from lazy import lazy <EOL> from selenium . common . exceptions import WebDriverException <EOL> from . query import BrowserQuery <EOL> from . promise import Promise , EmptyPromise , BrokenPromise <EOL> from . a11y import AxeCoreAudit , AxsAudit <EOL> XSS_INJECTION = "<STR_LIT>" <EOL> EXPECTED_ATTRIBUTE_FORMAT = re . compile ( r'<STR_LIT>' ) <EOL> XSS_HTML = "<STR_LIT>" <EOL> class WrongPageError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class PageLoadError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class XSSExposureError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def unguarded ( method ) : <EOL> """<STR_LIT>""" <EOL> method . _unguarded = True <EOL> return method <EOL> def pre_verify ( method ) : <EOL> """<STR_LIT>""" <EOL> @ wraps ( method ) <EOL> def wrapper ( self , * args , ** kwargs ) : <EOL> self . _verify_page ( ) <EOL> return method ( self , * args , ** kwargs ) <EOL> return wrapper <EOL> class _PageObjectMetaclass ( ABCMeta ) : <EOL> """<STR_LIT>""" <EOL> ALWAYS_UNGUARDED = [ '<STR_LIT:url>' , '<STR_LIT>' ] <EOL> def __new__ ( mcs , cls_name , cls_bases , cls_attrs ) : <EOL> for name , attr in cls_attrs . items ( ) : <EOL> if getattr ( attr , '<STR_LIT>' , False ) or name in mcs . ALWAYS_UNGUARDED : <EOL> continue <EOL> if name . startswith ( '<STR_LIT:_>' ) : <EOL> continue <EOL> if isinstance ( attr , type ) : <EOL> continue <EOL> is_property = isinstance ( attr , property ) <EOL> if not ( callable ( attr ) or is_property ) : <EOL> continue <EOL> if is_property : <EOL> property_methods = defaultdict ( None ) <EOL> for fn_name in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) : <EOL> prop_fn = getattr ( cls_attrs [ name ] , fn_name , None ) <EOL> if prop_fn is not None : <EOL> if getattr ( prop_fn , '<STR_LIT>' , False ) : <EOL> property_methods [ fn_name ] = prop_fn <EOL> else : <EOL> property_methods [ fn_name ] = pre_verify ( prop_fn ) <EOL> cls_attrs [ name ] = property ( ** property_methods ) <EOL> else : <EOL> cls_attrs [ name ] = pre_verify ( attr ) <EOL> return super ( _PageObjectMetaclass , mcs ) . __new__ ( mcs , cls_name , cls_bases , cls_attrs ) <EOL> class PageObject ( object ) : <EOL> """<STR_LIT>""" <EOL> __metaclass__ = _PageObjectMetaclass <EOL> def __init__ ( self , browser , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> super ( PageObject , self ) . __init__ ( * args , ** kwargs ) <EOL> self . browser = browser <EOL> a11y_flag = os . environ . get ( '<STR_LIT>' , '<STR_LIT:False>' ) <EOL> self . verify_accessibility = a11y_flag . lower ( ) == '<STR_LIT:true>' <EOL> xss_flag = os . environ . get ( '<STR_LIT>' , '<STR_LIT:False>' ) <EOL> self . verify_xss = xss_flag . lower ( ) == '<STR_LIT:true>' <EOL> @ lazy <EOL> def a11y_audit ( self ) : <EOL> """<STR_LIT>""" <EOL> rulesets = { <EOL> "<STR_LIT>" : AxeCoreAudit , <EOL> "<STR_LIT>" : AxsAudit , <EOL> } <EOL> ruleset = rulesets [ <EOL> os . environ . get ( "<STR_LIT>" , '<STR_LIT>' ) ] <EOL> return ruleset ( self . browser , self . url ) <EOL> @ abstractmethod <EOL> def is_browser_on_page ( self ) : <EOL> """<STR_LIT>""" <EOL> return False <EOL> @ abstractproperty <EOL> def url ( self ) : <EOL> """<STR_LIT>""" <EOL> return None <EOL> @ unguarded <EOL> def warning ( self , msg ) : <EOL> """<STR_LIT>""" <EOL> log = logging . getLogger ( self . __class__ . __name__ ) <EOL> log . warning ( msg ) <EOL> @ unguarded <EOL> def visit ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . url is None : <EOL> raise NotImplementedError ( "<STR_LIT>" . format ( self ) ) <EOL> if not self . validate_url ( self . url ) : <EOL> raise PageLoadError ( "<STR_LIT>" . format ( self . url ) ) <EOL> try : <EOL> self . browser . get ( self . url ) <EOL> except ( WebDriverException , socket . gaierror ) : <EOL> raise PageLoadError ( "<STR_LIT>" . format ( <EOL> self , self . url <EOL> ) ) <EOL> try : <EOL> return self . wait_for_page ( ) <EOL> except BrokenPromise : <EOL> raise PageLoadError ( "<STR_LIT>" . format ( <EOL> self , self . url <EOL> ) ) <EOL> @ classmethod <EOL> @ unguarded <EOL> def validate_url ( cls , url ) : <EOL> """<STR_LIT>""" <EOL> result = urlparse . urlsplit ( url ) <EOL> if not result . scheme or not result . netloc : <EOL> return False <EOL> try : <EOL> if result . port is not None : <EOL> int ( result . port ) <EOL> elif result . netloc . endswith ( '<STR_LIT::>' ) : <EOL> return False <EOL> except ValueError : <EOL> return False <EOL> else : <EOL> return True <EOL> def _verify_page ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . is_browser_on_page ( ) : <EOL> msg = "<STR_LIT>" . format ( <EOL> self , self . url <EOL> ) <EOL> raise WrongPageError ( msg ) <EOL> def _verify_xss_exposure ( self ) : <EOL> """<STR_LIT>""" <EOL> html_source = self . browser . execute_script ( <EOL> "<STR_LIT>" <EOL> ) <EOL> all_hits_count = html_source . count ( XSS_HTML ) <EOL> if all_hits_count > <NUM_LIT:0> : <EOL> safe_hits_count = len ( EXPECTED_ATTRIBUTE_FORMAT . findall ( html_source ) ) <EOL> if all_hits_count > safe_hits_count : <EOL> potential_hits = re . findall ( '<STR_LIT>' , html_source ) <EOL> raise XSSExposureError ( <EOL> "<STR_LIT>" . format ( <EOL> all_hits_count - safe_hits_count , potential_hits <EOL> ) <EOL> ) <EOL> @ unguarded <EOL> def wait_for_page ( self , timeout = <NUM_LIT:30> ) : <EOL> """<STR_LIT>""" <EOL> def _is_document_ready ( ) : <EOL> """<STR_LIT>""" <EOL> return self . browser . execute_script ( <EOL> "<STR_LIT>" ) <EOL> EmptyPromise ( <EOL> _is_document_ready , <EOL> "<STR_LIT>" , <EOL> timeout = timeout <EOL> ) . fulfill ( ) <EOL> result = Promise ( <EOL> lambda : ( self . is_browser_on_page ( ) , self ) , "<STR_LIT>" . format ( self ) , <EOL> timeout = timeout <EOL> ) . fulfill ( ) <EOL> if self . verify_accessibility : <EOL> self . a11y_audit . check_for_accessibility_errors ( ) <EOL> return result <EOL> @ unguarded <EOL> def q ( self , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> if self . verify_xss : <EOL> self . _verify_xss_exposure ( ) <EOL> return BrowserQuery ( self . browser , ** kwargs ) <EOL> @ contextmanager <EOL> def handle_alert ( self , confirm = True ) : <EOL> """<STR_LIT>""" <EOL> script = dedent ( """<STR_LIT>""" . format ( "<STR_LIT:true>" if confirm else "<STR_LIT:false>" ) ) . strip ( ) <EOL> self . browser . execute_script ( script ) <EOL> yield <EOL> @ unguarded <EOL> def wait_for_ajax ( self , timeout = <NUM_LIT:30> ) : <EOL> """<STR_LIT>""" <EOL> def _is_ajax_finished ( ) : <EOL> """<STR_LIT>""" <EOL> return self . browser . execute_script ( <EOL> "<STR_LIT>" ) <EOL> EmptyPromise ( <EOL> _is_ajax_finished , <EOL> "<STR_LIT>" , <EOL> timeout = timeout <EOL> ) . fulfill ( ) <EOL> @ unguarded <EOL> def wait_for ( self , promise_check_func , description , result = False , timeout = <NUM_LIT> ) : <EOL> """<STR_LIT>""" <EOL> if result : <EOL> return Promise ( promise_check_func , description , timeout = timeout ) . fulfill ( ) <EOL> else : <EOL> return EmptyPromise ( promise_check_func , description , timeout = timeout ) . fulfill ( ) <EOL> @ unguarded <EOL> def wait_for_element_presence ( self , element_selector , description , timeout = <NUM_LIT> ) : <EOL> """<STR_LIT>""" <EOL> self . wait_for ( lambda : self . q ( css = element_selector ) . present , description = description , timeout = timeout ) <EOL> @ unguarded <EOL> def wait_for_element_absence ( self , element_selector , description , timeout = <NUM_LIT> ) : <EOL> """<STR_LIT>""" <EOL> self . wait_for ( lambda : not self . q ( css = element_selector ) . present , description = description , timeout = timeout ) <EOL> @ unguarded <EOL> def wait_for_element_visibility ( self , element_selector , description , timeout = <NUM_LIT> ) : <EOL> """<STR_LIT>""" <EOL> self . wait_for ( lambda : self . q ( css = element_selector ) . visible , description = description , timeout = timeout ) <EOL> @ unguarded <EOL> def wait_for_element_invisibility ( self , element_selector , description , timeout = <NUM_LIT> ) : <EOL> """<STR_LIT>""" <EOL> self . wait_for ( lambda : self . q ( css = element_selector ) . invisible , description = description , timeout = timeout ) <EOL> @ unguarded <EOL> def scroll_to_element ( self , element_selector , timeout = <NUM_LIT> ) : <EOL> """<STR_LIT>""" <EOL> msg = "<STR_LIT>" . format ( element = element_selector ) <EOL> self . wait_for ( lambda : self . q ( css = element_selector ) . present , msg , timeout = timeout ) <EOL> loc = self . q ( css = element_selector ) . first . results [ <NUM_LIT:0> ] . location <EOL> self . browser . execute_script ( "<STR_LIT>" . format ( x = loc [ '<STR_LIT:x>' ] , y = loc [ '<STR_LIT:y>' ] ) ) </s>
