def test_undefined_token_env_variable_leads_to_exception_raised(monkeypatch): monkeypatch.delenv("TP_DEV_TOKEN", raising=False) with pytest.raises(SdkException) as sdke: ConfigHelper.get_developer_token() assert str( sdke.value ) == "No development token defined in TP_DEV_TOKEN environment variable"
def test_agent_env_with_trailing_slash_is_handled_correctly(monkeypatch): monkeypatch.setenv("TP_AGENT_URL", "http://localhost:8585/") agent_address = ConfigHelper.get_agent_service_address() assert ( urljoin(agent_address, Endpoint.DevelopmentSession.value) == "http://127.0.0.1:8585/api/development/session" )
def __init__(self, capabilities: dict, report_settings: ReportSettings): self._capabilities: dict = capabilities self._sdk_version = ConfigHelper.get_sdk_version() self._language = "Python" self._project_name = report_settings.project_name self._job_name = report_settings.job_name self._report_type = report_settings.report_type
def __start_session(self) -> bool: """Starts a new development session with the Agent Returns: bool: True if the session started successfully, False otherwise """ sdk_version = ConfigHelper.get_sdk_version() logging.info(f"SDK version: {sdk_version}") start_session_response = self._request_session_from_agent() AgentClient.__agent_version = start_session_response.agent_version self._agent_session = AgentSession( start_session_response.server_address, start_session_response.session_id, start_session_response.dialect, start_session_response.capabilities, ) SocketManager.instance().open_socket( self._remote_address, start_session_response.dev_socket_port) logging.info("Development session started...") return True
def __init__( self, token: str = None, projectname: str = None, jobname: str = None, disable_reports: bool = False, ): if Generic.__instance is not None: raise SdkException("A driver session already exists") LoggingHelper.configure_logging() self._token = token if token is not None else ConfigHelper.get_developer_token( ) agent_status_response: AgentStatusResponse = AgentClient.get_agent_version( self._token) if version.parse(agent_status_response.tag) < version.parse( Generic.MIN_GENERIC_DRIVER_SUPPORTED_VERSION): raise AgentConnectException( f"Your current Agent version {agent_status_response.tag} does not support the Generic driver. " f"Please upgrade your Agent to the latest version and try again" ) else: logging.info( f"Current Agent version {agent_status_response.tag} does support Generic driver" ) self.session_id = None if disable_reports: # Setting the project and job name to empty strings will cause the Agent to not initialize a report self._projectname = "" self._jobname = "" else: self._projectname = (projectname if projectname is not None else ReportHelper.infer_project_name()) self._jobname = (jobname if jobname is not None else ReportHelper.infer_job_name()) reportsettings = ReportSettings(self._projectname, self._jobname) capabilities = {"platformName": "ANY"} self._agent_client: AgentClient = AgentClient( token=self._token, capabilities=capabilities, report_settings=reportsettings, ) self._agent_session: AgentSession = self._agent_client.agent_session self.command_executor = GenericCommandExecutor( agent_client=self._agent_client) Generic.__instance = self
def __init__( self, capabilities: dict, token: str, projectname: str, jobname: str, disable_reports: bool, ): if BaseDriver.__instance is not None: raise SdkException("A driver session already exists") LoggingHelper.configure_logging() if token is not None: logging.info(f"Token used as specified in constructor: {token}") self._token = token if token is not None else ConfigHelper.get_developer_token( ) if disable_reports: # Setting the project and job name to empty strings will cause the Agent to not initialize a report self._projectname = "" self._jobname = "" else: self._projectname = (projectname if projectname is not None else ReportHelper.infer_project_name()) self._jobname = (jobname if jobname is not None else ReportHelper.infer_job_name()) self._agent_client: AgentClient = AgentClient( token=self._token, capabilities=capabilities, reportsettings=ReportSettings(self._projectname, self._jobname), ) self._agent_session: AgentSession = self._agent_client.agent_session self.w3c = True if self._agent_session.dialect == "W3C" else False # Create a custom command executor to enable: # - automatic logging capabilities # - customized reporting settings self.command_executor = CustomCommandExecutor( agent_client=self._agent_client, remote_server_addr=self._agent_session.remote_address, ) self.command_executor.disable_reports = disable_reports RemoteWebDriver.__init__( self, command_executor=self.command_executor, desired_capabilities=self._agent_session.capabilities, ) BaseDriver.__instance = self
def __init__( self, desired_capabilities: dict = None, token: str = None, project_name: str = None, job_name: str = None, disable_reports: bool = False, ): if Remote.__instance is not None: raise SdkException("A driver session already exists") LoggingHelper.configure_logging() self._desired_capabilities = desired_capabilities self._token = token if token is not None else ConfigHelper.get_developer_token( ) if disable_reports: # Setting the project and job name to empty strings will cause the Agent to not initialize a report self._project_name = "" self._job_name = "" else: self._project_name = (project_name if project_name is not None else ReportHelper.infer_project_name()) self._job_name = (job_name if job_name is not None else ReportHelper.infer_job_name()) report_settings = ReportSettings(self._project_name, self._job_name) self._agent_client: AgentClient = AgentClient( token=self._token, capabilities=self._desired_capabilities, report_settings=report_settings, ) self._agent_session: AgentSession = self._agent_client.agent_session self.w3c = True if self._agent_session.dialect == "W3C" else False AppiumWebDriver.__init__( self, command_executor=self._agent_session.remote_address, desired_capabilities=self._desired_capabilities, ) self.command_executor = CustomAppiumCommandExecutor( agent_client=self._agent_client, remote_server_addr=self._agent_session.remote_address, ) # this ensures that mobile-specific commands are also available for our command executor self._addCommands() Remote.__instance = self
def __init__(self, token: str, capabilities: dict, report_settings: ReportSettings): self._remote_address = ConfigHelper.get_agent_service_address() self._capabilities = capabilities self._agent_session = None self._token = token self._report_settings = report_settings self._queue = queue.Queue() self._running = True self._reporting_thread = threading.Thread(target=self.__report_worker, daemon=True) self._reporting_thread.start() if not self.__start_session(): raise SdkException("Failed to start development mode session")
def __init__(self, token: str, capabilities: dict, report_settings: ReportSettings): self._agent_session = None self._agent_response = None self._close_socket = False self._remote_address = ConfigHelper.get_agent_service_address() self._report_settings = report_settings self._capabilities = capabilities self._token = token # Attempt to start the session self.__start_session() # Make sure local reports are supported self.__verify_local_reports_supported(report_settings.report_type) # Running after all is initialized successfully self._running = True # After session started and is running, start the reporting thread self._queue = queue.Queue() self._reporting_thread = threading.Thread(target=self.__report_worker, daemon=True) self._reporting_thread.start()
def __start_session(self): """Starts a new development session with the Agent""" sdk_version = ConfigHelper.get_sdk_version() logging.info(f"SDK version: {sdk_version}") self._request_session_from_agent() AgentClient.__agent_version = self._agent_response.agent_version self._agent_session = AgentSession( self._agent_response.server_address, self._agent_response.session_id, self._agent_response.dialect, self._agent_response.capabilities, ) SocketManager.instance().open_socket( urlparse(self._remote_address).hostname, self._agent_response.dev_socket_port, ) logging.info("Development session started...")
def get_agent_version(token: str): """Requests the current Agent status Args: token (str): The developer token used to communicate with the Agent Returns: AgentStatusResponse: contains the response to the sent Agent status request """ with requests.Session() as session: response = session.get( urljoin(ConfigHelper.get_agent_service_address(), Endpoint.GetStatus.value), headers={"Authorization": token}, ) try: response.raise_for_status() try: response_json = response.json() agent_version = response_json["tag"] except ValueError: raise SdkException( "Could not parse Agent status response: no JSON response body present" ) except KeyError: raise SdkException( "Could not parse Agent status response: element 'tag' not found in JSON response body" ) except HTTPError: raise AgentConnectException( f"Agent returned HTTP {response.status_code} when trying to retrieve Agent status" ) return AgentStatusResponse(agent_version)
def test_predefined_token_env_variable_resolves_to_specified_value(monkeypatch): monkeypatch.setenv("TP_DEV_TOKEN", "some_token") assert ConfigHelper.get_developer_token() == "some_token"
def test_predefined_agent_env_variable_resolves_to_specified_value(monkeypatch): monkeypatch.setenv("TP_AGENT_URL", "some_address") assert ConfigHelper.get_agent_service_address() == "some_address"
def test_undefined_agent_env_variable_resolves_to_default_agent_service_address( monkeypatch, ): monkeypatch.delenv("TP_AGENT_URL", raising=False) assert ConfigHelper.get_agent_service_address() == "http://127.0.0.1:8585"
def __init__( self, desired_capabilities: dict = None, token: str = None, project_name: str = None, job_name: str = None, disable_reports: bool = False, ): if Remote.__instance is not None: raise SdkException("A driver session already exists") LoggingHelper.configure_logging() self._desired_capabilities = desired_capabilities self._token = token if token is not None else ConfigHelper.get_developer_token( ) if disable_reports: # Setting the project and job name to empty strings will cause the Agent to not initialize a report self._project_name = "" self._job_name = "" else: self._project_name = (project_name if project_name is not None else ReportHelper.infer_project_name()) if job_name: self._job_name = job_name else: self._job_name = ReportHelper.infer_job_name() # Can update job name at runtime if not specified. os.environ[ EnvironmentVariable.TP_UPDATE_JOB_NAME.value] = "True" report_settings = ReportSettings(self._project_name, self._job_name) self._agent_client: AgentClient = AgentClient( token=self._token, capabilities=self._desired_capabilities, report_settings=report_settings, ) self._agent_session: AgentSession = self._agent_client.agent_session self.w3c = True if self._agent_session.dialect == "W3C" else False AppiumWebDriver.__init__( self, command_executor=self._agent_session.remote_address, desired_capabilities=self._desired_capabilities, ) self.command_executor = CustomAppiumCommandExecutor( agent_client=self._agent_client, remote_server_addr=self._agent_session.remote_address, ) # this ensures that mobile-specific commands are also available for our command executor self._addCommands() # Disable automatic command and test reports if Behave reporting is enabled. if os.getenv("TP_DISABLE_AUTO_REPORTING") == "True": self.command_executor.disable_command_reports = True self.command_executor.disable_auto_test_reports = True Remote.__instance = self
# # 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. # See the License for the specific language governing permissions and # limitations under the License. import pytest from packaging import version from src.testproject.helpers import ConfigHelper from src.testproject.sdk.drivers import webdriver from selenium.webdriver import ChromeOptions from tests.pageobjects.web import LoginPage, ProfilePage if version.parse(ConfigHelper.get_sdk_version()) < version.parse("0.64.0"): pytest.skip('This feature is not supported in SDK versions < 0.64.0', allow_module_level=True) @pytest.fixture def driver(): chrome_options = ChromeOptions() chrome_options.headless = True driver = webdriver.Chrome(chrome_options=chrome_options, project_name="CI - Python") yield driver driver.quit() def test_update_profile_expect_success_message_to_be_displayed(driver):
def __init__( self, capabilities: dict, token: str, project_name: str, job_name: str, disable_reports: bool, report_type: ReportType, ): if BaseDriver.__instance is not None: raise SdkException("A driver session already exists") LoggingHelper.configure_logging() if token is not None: logging.info(f"Token used as specified in constructor: {token}") self._token = token if token is not None else ConfigHelper.get_developer_token( ) if disable_reports: # Setting the project and job name to empty strings will cause the Agent to not initialize a report self._project_name = "" self._job_name = "" else: self._project_name = project_name if project_name is not None else ReportHelper.infer_project_name( ) if job_name: self._job_name = job_name else: self._job_name = ReportHelper.infer_job_name() # Can update job name at runtime if not specified. os.environ[ EnvironmentVariable.TP_UPDATE_JOB_NAME.value] = "True" self._agent_client: AgentClient = AgentClient( token=self._token, capabilities=capabilities, report_settings=ReportSettings(self._project_name, self._job_name, report_type), ) self._agent_session: AgentSession = self._agent_client.agent_session self.w3c = True if self._agent_session.dialect == "W3C" else False # Create a custom command executor to enable: # - automatic logging capabilities # - customized reporting settings self.command_executor = CustomCommandExecutor( agent_client=self._agent_client, remote_server_addr=self._agent_session.remote_address, ) self.command_executor.disable_reports = disable_reports # Disable automatic command and test reports if Behave reporting is enabled. if os.getenv("TP_DISABLE_AUTO_REPORTING") == "True": self.command_executor.disable_command_reports = True self.command_executor.disable_auto_test_reports = True RemoteWebDriver.__init__( self, command_executor=self.command_executor, desired_capabilities=self._agent_session.capabilities, ) BaseDriver.__instance = self