Professional mobile web testing framework using Selenium WebDriver with Chrome mobile emulation, CI/CD integration, and production-grade test stability patterns.
- Mobile web testing with Chrome emulation (Pixel 5: 393x851)
- Parametrized tests using pytest.mark.parametrize
- CI/CD integration with GitHub Actions
- HTML test execution reports
- Robust error handling and stability patterns
- Cross-environment execution (local GUI and CI/CD headless)
| Test Suite | Description | Status |
|---|---|---|
| Google Search | Mobile search functionality | Passing |
| Wikipedia | Article search and navigation | Passing |
| Amazon | Product search validation | Skipped |
| Contact Forms | Form submission and validation | Passing |
| Multi-language Navigation | Parametrized tests (ES, EN, FR) | Passing |
Total: 5 test files, 8 test cases (7 passing, 1 skipped)
Note: Amazon test is intentionally skipped due to bot detection. See "Known Challenges" section.
- Python 3.11
- Selenium WebDriver 4.39
- pytest 9.0 with parametrize
- webdriver-manager 4.0
- pytest-html 4.1
- Chrome Mobile Emulation (Pixel 5)
- GitHub Actions CI/CD
QA_Mobile_Appium/
├── .github/workflows/
│ └── tests.yml # CI/CD pipeline configuration
├── tests/
│ ├── test_web_mobile.py # Google and Wikipedia tests
│ ├── test_amazon_mobile.py # Amazon (skipped - bot detection)
│ ├── test_form_mobile.py # Form submission tests
│ └── test_navigation_mobile.py # Parametrized multi-language
├── config/
│ └── appium_config.py
├── reports/
│ └── report.html # HTML test execution report
├── screenshots/
│ └── *.png # Test execution screenshots
├── conftest.py # Centralized pytest fixtures
├── pytest.ini # Pytest configuration
├── requirements.txt
└── README.md
# Clone repository
git clone https://github.com/arturdmt-alt/QA_Mobile_Appium.git
cd QA_Mobile_Appium
# Create virtual environment
python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows
# Install dependencies
pip install -r requirements.txt# Run all tests
pytest tests/ -v
# Run with HTML report
pytest tests/ -v --html=reports/report.html --self-contained-html
# Run specific test file
pytest tests/test_web_mobile.py -v
# Run parametrized tests only
pytest tests/test_navigation_mobile.py -vThe navigation test uses @pytest.mark.parametrize to execute multiple test variations:
@pytest.mark.parametrize(
"language_id, expected_domain",
[
("js-link-box-es", "es.wikipedia"),
("js-link-box-en", "en.wikipedia"),
("js-link-box-fr", "fr.wikipedia"),
]
)
def test_mobile_navigation_by_language(self, driver, language_id, expected_domain):
# Single test function executes 3 times with different parametersBenefits:
- Follows DRY principles
- Scalable test design
- Data-driven testing approach
- Easy to extend with additional test cases
The conftest.py file provides a single fixture for all tests with automatic CI/CD detection:
@pytest.fixture(scope='function')
def driver():
# Automatically detects CI environment
if os.getenv("CI"):
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
# Mobile emulation configurationAdvantages:
- No duplicate code across test files
- Automatic environment detection
- Consistent test execution
tests/test_web_mobile.py::TestWebMobile::test_google_search_mobile PASSED
tests/test_web_mobile.py::TestWebMobile::test_wikipedia_mobile PASSED
tests/test_amazon_mobile.py::TestAmazonMobile::test_amazon_search_mobile SKIPPED
tests/test_form_mobile.py::TestFormMobile::test_contact_form_mobile PASSED
tests/test_navigation_mobile.py::TestNavigationMobile::test_mobile_navigation_by_language[es] PASSED
tests/test_navigation_mobile.py::TestNavigationMobile::test_mobile_navigation_by_language[en] PASSED
tests/test_navigation_mobile.py::TestNavigationMobile::test_mobile_navigation_by_language[fr] PASSED
Status: 7 passing, 1 skipped (Amazon - bot protection)
View full HTML report: reports/report.html
Challenge: Initial CI/CD implementation revealed cascading failures across workflows #1-#8
Root Cause: Multiple issues including ChromeDriver installation, webdriver-manager dependencies, headless mode configuration, and duplicate fixtures in test setup.
Solution:
- Added ChromeDriver installation step in CI workflow
- Configured headless mode for CI environment
- Removed duplicate fixtures causing test interference
- Stabilized overlay handling with JavaScript clicks
Current Status:
- All 7 mobile web tests passing
- CI/CD pipeline stable (workflows #9, #10, #11)
- Full test coverage with evidence screenshots
- Zero flaky tests
Key Takeaway: Mobile testing in CI requires careful configuration of browser drivers, headless modes, and handling of dynamic web elements. This debugging journey demonstrates real-world problem-solving in mobile automation.
This section documents real automation challenges encountered and their professional solutions.
Problem: Amazon actively blocks automated headless browsers using bot detection algorithms, CAPTCHA challenges, and dynamic rendering.
Impact:
- Causes unstable test results in CI/CD environments
- Produces false negatives
- Breaks CI pipeline reliability
Solution:
The Amazon test is marked with @pytest.mark.skip:
@pytest.mark.skip(
reason="Amazon blocks automated headless browsers with bot detection in CI environments"
)Rationale:
- Prevents false negatives in CI pipeline
- Maintains overall test suite stability
- Documents system limitations transparently
- Demonstrates QA decision-making over blind automation
Alternative approaches considered:
- Selenium Stealth plugins - Not maintainable long-term
- Real device testing with Appium - Outside current project scope
- API-level testing - Better approach for comprehensive validation
Problem:
In headless CI mode, Wikipedia displays overlay banners that block element clicks, causing ElementClickInterceptedException. Tests pass locally but fail in CI.
Solution: Implemented overlay detection and removal before clicking:
try:
overlay = driver.find_element(By.CSS_SELECTOR, ".overlay-banner")
driver.execute_script("arguments[0].remove();", overlay)
except:
pass
# JavaScript-based click as fallback
driver.execute_script("arguments[0].click();", language_link)Results:
- Stable navigation tests across all environments
- Zero flaky tests
- Handles real user-facing UI behavior
Key differences handled:
| Aspect | Local Environment | CI/CD Environment |
|---|---|---|
| Browser Mode | GUI | Headless |
| Rendering | Full rendering | Optimized rendering |
| Execution Speed | Fast | Variable |
| Overlays/Popups | Rare | Frequent |
Techniques applied:
- Explicit waits with WebDriverWait
- Poll frequency tuning for reliability
- JavaScript execution as fallback
- Conditional CI environment detection
- Comprehensive try/except error handling
GitHub Actions workflow includes:
- Automated test execution on every push
- Chrome browser installation in Linux environment
- Headless browser support for CI
- HTML report artifacts
- Status badge for real-time monitoring
Current status:
- 7 tests passing consistently
- 1 test skipped with documentation
- 0 flaky tests
- Green CI pipeline on every commit
Artur Dmytriyev
QA Automation Engineer
- LinkedIn: linkedin.com/in/arturdmytriyev
- GitHub: github.com/arturdmt-alt
If you found this project helpful, give it a star on GitHub!