# Selenium-based Test Automation Framework for the Apollo Portal application

Overview
=============
* Framework is based on the page object model.
* Added Allure as reporting tool.
* Locators are stored in JSON file.
* Reading test data from JSON file.
* Reading credentials from environment varibales.
* Integrated API client.
* Integrated DB client.
* Supports verification and asserts from unittest and native Python assert.
* Supports taking screenshots during failure and verification step.

SETUP:
===

Install locally:
any selenium server can be used to run tests - configs should be specified in .env file(please see .env.sample file)

there are already specified configurations for chromedriver and selenoid in framework/core/webdriver_factory.py 


Install requirements and dependencies:
sh
pip install --index=https://artifacts.apollo.stream/repository/pypi-all/pypi --index-url=https://artifacts.apollo.stream/repository/pypi-all/simple ui_automation_framework --proxy http://91.234.37.233:3128
install each constant from .env through terminal command: set USER_EMAIL=, ...

MAKE CHANGES IN CORE:
====
make PR and push to master https://github.com/filtr/ui-automation-framework-pkg
do not forget to: make version/patch
run build https://jenkins.apollo.stream/job/DNA/job/ui-automation-framework-pkg/job/master/
after build completed:
pip install --index=https://artifacts.apollo.stream/repository/pypi-all/pypi --index-url=https://artifacts.apollo.stream/repository/pypi-all/simple ui_automation_framework=={NEW_VERSION}


RUN:
====

Run all tests:
sh
make test


Run specific test suite:
sh
py.test --html=report.html --self-contained-html  --alluredir=allure_report app/src/tests/test_track_page.py -n 4 --reruns 1


To run tests in parallel add option:

-n {streams_count}


To add reruns for failed test:

--reruns {reruns_count}


REPORTING:
===
Both Allure and pytests reports are available

Generating allure report:
sh
make report

PyTest report is available after run as report.html file

CONFIGURATION OF THE FRAMEWORK
===
All test-data related configuration is stored under app/config/config.json file.

    [{
    "spotify_trackId": "1rgnBhdG2JDFTbYkYRZAku",
    "spotify_track_isrc": "QZES71982312"
    }]
    
And read the required field with AppConfig reader:

    self.api_client = ApiClient(AppConfig.get("api_auth_url"), AppConfig.get("qa_api_url"), 60)
    
From data safety perspective all credentials should be stored in env variables and can be readed via CoreConfig:

    self.token_portal = self.api_client.authorize(CoreConfig.AUTH0_CLIENT_ID, CoreConfig.AUTH0_CLIENT_SECRET) 


CREATION OF YOUR OWN UI TEST:
===
All application-related code is stored in app/ directory.
Pages, actions and business logic are stored in app/pages/ directory and named accordingly to represented page.

    @allure.step("verifying successful login with valid credentials")
    def login(self, email, password):
        self.wait_for_element_visible(*self.locator(self.login_locators, "sign_in"))
        self.click_element(*self.locator(self.login_locators, "sign_in"))
        self.wait_for_element_visible(*self.locator(self.login_locators, "email_field"))
        self.click_element(*self.locator(self.login_locators, "email_field"))
        self.send_text(email, *self.locator(self.login_locators, "email_field"))
        self.click_element(*self.locator(self.login_locators, "password_field"))
        self.send_text(password, *self.locator(self.login_locators, "password_field"))
        self.click_element(*self.locator(self.login_locators, "login_btn"))

UI elements described in app/element/ directory  in JSON files named accordingly to represented page. Locator description includes related page, location strategy (xpath, css..) and locator itself.

         [{
            "pageName": "LoginPage",
            "name": "login_button",
            "locateUsing": "xpath",
            "locator": "//a[contains(text(),'Log In')]"
         }]

Tests are stored in app/tests/ dir and describe test flow, test file should contain 'test' in file name in order to pytest can collect it (test_login.py)':

    @allure.story("POC scope")
    @allure.severity(allure.severity_level.CRITICAL)
    @allure.title("Verifying all users notifications")
    def test_login(self):
        login = CoreConfig.NOTIFICATIONS_EMAIL
        password = CoreConfig.NOTIFICATIONS_PASSWORD

        self.loginPage.login(login, password)
        self.ts.markFinal(self.loginPage.is_logged_in(), "user is logged in")

CREATION OF YOUR OWN API TEST:
===
API helper available under framework/api/ directory. Just add your endpoint description in appropriate client and don't forget to import it in your test.

    @allure.step("Getting portal playlists data from /spotify/filtr-track-playlists/?")
    def get_spotify_playlists_data_portal(self, *parameters, token):
        headers = {'authorization': 'Bearer {}'.format(token)}
        api_string = '/apollo-api/spotify/filtr-track-playlists/?'

        params_list = "&".join(parameters)
        resp = self._s.get(self.host_endpoint + api_string + params_list,
                           headers=headers, timeout=self.timeout)
        self.log.info(self.host_endpoint + api_string + params_list)
        response = {'status_code': resp.status_code, 'body': resp.json()}
        self.log.info(response)
        return response


    portal_start = self.api_client.get_spotify_playlists_data_portal("trackID=2ksOAxtIxY8yElEWw8RhgK",
                                                                     "limit=100",
                                                                     "offset=100",
                                                                     "market=us",
                                                                     token=self.token_mobile)
    total_potal = portal_start['body']['pagination']['total']
    
    
ESTABLISHING DATABASE CONNECTION:
===
In order to connect to the data base make sure your has tunnel into Sony area up and running.
Set the following creds in env variables:

MYSQL_DB_NAME
MYSQL_DB_HOST
MYSQL_DB_PORT
MYSQL_DB_USER
MYSQL_DB_PASS

And pass it to the DB helper:

    self.sql_client = MySqlClient(
            host=CoreConfig.MYSQL_DB_HOST,
            database=CoreConfig.MYSQL_DB_NAME,
            user=CoreConfig.MYSQL_DB_USER,
            password=CoreConfig.MYSQL_DB_PASS,
        )
        
Add your own queries to framework/db/mysql_db_client.py


USING MOCKED RESPONSE DATA(Works only for local runs):
===
TBD

TAKING SCREENSHOTS
===
Screenshots will be automatically taken during failure and attached to the allure report.
All screenshots will be saved under app/screenshots/ dir. If you want to take the screenshot on verification step use markFinal method from utils:

    from framework.core import TestStatus
    
    self.ts = TestStatus(self.driver)
    self.ts.markFinal(self.searchPage.is_track_starred(track_name), "The track is starred on full charts")
    
AFTER PUSH TO master in ui_automation_framework_pkg repo:
- run using cygwin: 'make docker/push' from framework folder(cygwin and docker installed)

**BEFORE COMMIT:**
Run locally:
make docker/pre-commit (can be run using GitBash only - Windows)

**WINDOWS configuration**(run only once):
1. AWS CLI should be installed and properly setup
2. add files with config to path-C:\Users\%HOME_DIRECTORY%\.aws: config, credentials.
3. Link to doc: https://data-analytics.atlassian.net/wiki/spaces/IN/pages/218398747/AWS+user+guide?NO_SSR=1
4. AWS user should be created - devops can help
5. Using PowerShell(as admin) run:
6. set-executionpolicy -executionpolicy unrestricted
7. Install-Module AWSPowershell
8. Using PowerShell(non admin) run:
9. Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
10. ./assumed_role_as_default.ps1 gdb-delphi-dev MFA_CODE_AWS_USER
11. aws ecr get-login-password | docker login --username AWS --password-stdin https://475275892927.dkr.ecr.us-east-1.amazonaws.com
12. docker build --target dev -t 475275892927.dkr.ecr.us-east-1.amazonaws.com/apollo/ui-test-selinoid-runner:testing .

**macOS configuration**(run only once):
1. Need to install AWS CLI - https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html
2. You should have AWS user, if not devops can help with that
3. Need to sign-in to AWS console with aws user and change password (strong password should be)
   Console sign-in URL: https://gdb-infra-dev.signin.aws.amazon.com/console
4. Need to configure MFA with Google Authenticator and then re-login
   https://data-analytics.atlassian.net/wiki/spaces/IN/pages/218398768/AWS+Setting+up+MFA+with+Google+Authenticator
5. After that you should generate access key ID and secret access key:
   Under aws console -> User menu -> Security credentials -> Access keys section
6. Then you need to open .aws folder (it is the hidden one, so you need to change settings to show hidden folders)
   In the .aws folder you should update two files:
    - credentials file
    - config file
    https://data-analytics.atlassian.net/wiki/spaces/IN/pages/218398747/AWS+user+guide
7. Need to install docker, if not installed
8. When all steps done need to run "make docker/image/build" command in the PyCharm terminal (it is required only ones after all set up is done)
9. If previous command run successfully, before each commit you should run "make docker/pre-commit" command to validate code changes
