Run the sample web app visual test
Step 1: Setup environment
Requirements
- Python 3
- Pytest framework
- Appium client
- Access key
- You can generate an Access key using the following instruction – Access key
- Billing unit
- The billing unit is your team’s unique identifier, or just the word “personal” in the case of an individual account.
More information can be found here.
- The billing unit is your team’s unique identifier, or just the word “personal” in the case of an individual account.
Step 2: Add the interaction with visual testing API
After setup up the environment, you need to add the interaction with the visual testing API:
from typing import Optional
import pytest
import requests
from pydantic import BaseModel, Field
class VisualBuildInputData(BaseModel):
name: str
project: str
branch: str
class VisualSnapshotInputData(BaseModel):
name: str
build_id: str
image: Path
test_name: Optional[str]
suite_name: Optional[str]
browser: Optional[str]
class VisualBuildData(BaseModel):
id: str
name: str
project: str
branch: str
status: str
class VisualSnapshotData(BaseModel):
id: str
name: str
build_id: str = Field(alias="buildId")
test_name: str = Field(alias="testName")
suite_name: str = Field(alias="suiteName")
device: Optional[str]
class VisualTestingAPI:
def __init__(self, base_url: str, api_key: str):
self.base_url = base_url
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
self.api_key = api_key
def create_build(self, input_data: VisualBuildInputData) -> VisualBuildData:
url = f"{self.base_url}/builds"
response = requests.post(url, headers=self.headers, json=input_data.dict())
response.raise_for_status() # Raise an error if the request failed
return VisualBuildData(**response.json())
def finish_build(self, build_id: str) -> None:
url = f"{self.base_url}/builds/{build_id}/finish"
response = requests.post(url, headers=self.headers)
response.raise_for_status()
def submit_snapshot(self, data: VisualSnapshotInputData) -> VisualSnapshotData:
url = f"{self.base_url}/builds/{data.build_id}/snapshots"
files = {
"image": (data.image.name, open(data.image, "rb"), "image/png")
}
payload = {
"name": data.name,
"testName": data.test_name,
"suiteName": data.suite_name,
"browser": data.browser,
}
response = requests.post(url, headers={"Authorization": f"Bearer {self.api_key}"}, files=files, data=payload)
response.raise_for_status() # Raise an error if the request failed
return VisualSnapshotData(**response.json())
Step 3: Run sample test
After setup up the environment and integrating the visual testing API, you can run your first web visual test
import tempfile
from pathlib import Path
from typing import Optional
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
PROJECT_NAME = "--------- BILLING UNIT -----------"
ACCESS_KEY = "--------- YOUR ACCESS KEY -----------"
OPEN_URL = "https://mobitru.com/"
DEFAULT_PAGE_LOAD_TIMEOUT_SEC = 30
DEFAULT_IMPL_TIMEOUT_SEC = 3
DEFAULT_WAIT_TIMEOUT_SEC = 10
VISUAL_PROJECT_NAME = 'epm-tstf'
VISUAL_TESTING_API_HOST = "visual.mobitru.com"
VISUAL_TESTING_API_BASE_URL = f"https://{VISUAL_TESTING_API_HOST}/billing/unit/{PROJECT_NAME}/api/v1"
@pytest.fixture()
def visual_testing_api(request):
return VisualTestingAPI(base_url=VISUAL_TESTING_API_BASE_URL, api_key=ACCESS_KEY)
@pytest.fixture()
def visual_testing_build(visual_testing_api):
"""create a new build """
build_input_data = VisualBuildInputData(name='Build 1', project='Python Web Selenium Automation Demo',
branch='master')
build_data = visual_testing_api.create_build(build_input_data)
yield build_data
visual_testing_api.finish_build(build_data.id)
@pytest.fixture(scope="function")
def driver():
options = webdriver.ChromeOptions()
mobitru_options = {
'enableVideo': False,
'sessionTimeout': '1m',
}
options.set_capability('mobitru:options', mobitru_options)
cloud_url = f"https://{PROJECT_NAME}:{ACCESS_TOKEN}@browserhub-us.mobitru.com/wd/hub"
print(options.capabilities)
os.environ['WDM_SSL_VERIFY'] = '0'
driver = webdriver.Remote(cloud_url, options=options)
yield driver
# Cleanup
driver.quit()
def test_selenium_demo(driver, visual_testing_api, visual_testing_build):
"""Test to verify navigation to mobitru and basic checks."""
test_name = 'demo web selenium test'
# Ensure the app is a browser
# Navigate to the URL
driver.get(OPEN_URL)
# Wait for the Mobitru main page is opened
WebDriverWait(driver, DEFAULT_WAIT_TIMEOUT_SEC).until(
EC.presence_of_all_elements_located((By.CSS_SELECTOR, "button[class*='demo']")),
message="Page was not loaded"
)
# Verify the current URL
assert driver.current_url == OPEN_URL, "Current URL is incorrect."
# Verify the page title
assert driver.title == "Mobitru: Real Devices, Browsers & AI - in One Enterprise Testing Platform"
submit_snapshot(driver, result_name='after_open_url', test_name=test_name,
visual_build_data=visual_testing_build,
visual_testing_api=visual_testing_api)
def submit_snapshot(
driver,
result_name,
test_name,
visual_build_data: VisualBuildData,
visual_testing_api: VisualTestingAPI
) -> VisualSnapshotData:
# Capture a screenshot and return the temporary file path
screenshot_path = capture_screenshot(driver)
# Build VisualSnapshotInputData
snapshot_input_data = VisualSnapshotInputData(
name=result_name,
build_id=visual_build_data.id,
test_name=test_name,
browser=driver.capabilities.get('browserName'),
suite_name=visual_build_data.project, # Assuming suite name is the project name
image=screenshot_path # Screenshot file
)
return visual_testing_api.submit_snapshot(snapshot_input_data)
def capture_screenshot(driver) -> Path:
with tempfile.NamedTemporaryFile(mode='w+', delete=False, suffix=".png") as tmp_file:
# Get the path of the temporary file
screenshot_path = tmp_file.name
driver.save_screenshot(screenshot_path) # Save the screenshot
return Path(screenshot_path)