329 lines
7.0 KiB
Markdown
329 lines
7.0 KiB
Markdown
# Selenium UI Tests for Tilbudgivern
|
|
|
|
## Overview
|
|
|
|
This directory contains Selenium-based UI tests for the Tilbudgivern application. These tests simulate real user interactions with the browser to verify the complete user journey.
|
|
|
|
## Test Files
|
|
|
|
### 1. `carpenter_quote_test.py`
|
|
**Complete Carpenter Quote Creation Test**
|
|
|
|
Tests the full user flow:
|
|
- ✅ Navigate to application
|
|
- ✅ Login
|
|
- ✅ Create customer project
|
|
- ✅ Enter geometry data (area, dimensions)
|
|
- ✅ Select smart package
|
|
- ✅ Review materials and labor
|
|
- ✅ Generate quote
|
|
- ✅ Verify realism (materials, prices, labor)
|
|
- ✅ API validation
|
|
|
|
**Test Coverage:**
|
|
- 10 comprehensive tests
|
|
- Full user journey simulation
|
|
- Screenshots at each step
|
|
- Realism validation
|
|
- API verification
|
|
|
|
### 2. `stark_import_test.py`
|
|
**Stark Material Import Tests**
|
|
|
|
Tests Stark CSV import functionality:
|
|
- File upload
|
|
- Data processing
|
|
- Import history
|
|
- API endpoints
|
|
|
|
## Prerequisites
|
|
|
|
### 1. Python Requirements
|
|
```bash
|
|
pip install selenium requests
|
|
```
|
|
|
|
### 2. Chrome/Chromium Browser
|
|
```bash
|
|
# Ubuntu/Debian
|
|
sudo apt-get install chromium-browser
|
|
|
|
# Or use Google Chrome
|
|
```
|
|
|
|
### 3. ChromeDriver
|
|
ChromeDriver must match your Chrome version.
|
|
|
|
**Option A: Auto-install (recommended)**
|
|
```bash
|
|
pip install webdriver-manager
|
|
```
|
|
|
|
**Option B: Manual download**
|
|
1. Check Chrome version: `google-chrome --version`
|
|
2. Download matching ChromeDriver from: https://chromedriver.chromium.org/downloads
|
|
3. Add to PATH or place in `/usr/local/bin/`
|
|
|
|
### 4. Running Servers
|
|
Both servers must be running:
|
|
|
|
```bash
|
|
# Terminal 1: Backend
|
|
cd backend
|
|
node unified-server.js
|
|
|
|
# Terminal 2: Frontend
|
|
cd frontend
|
|
npm start
|
|
```
|
|
|
|
Verify:
|
|
- Backend: http://localhost:4031/health
|
|
- Frontend: http://localhost:3000
|
|
|
|
## Running Tests
|
|
|
|
### Quick Start
|
|
```bash
|
|
cd tests/selenium
|
|
./run_carpenter_tests.sh
|
|
```
|
|
|
|
### Manual Run
|
|
```bash
|
|
cd tests/selenium
|
|
python3 carpenter_quote_test.py
|
|
```
|
|
|
|
### Headless Mode
|
|
Edit test file and uncomment:
|
|
```python
|
|
options.add_argument('--headless')
|
|
```
|
|
|
|
## Test Results
|
|
|
|
### Screenshots
|
|
Screenshots are saved to: `tests/test-results/selenium-screenshots/`
|
|
|
|
Example screenshots:
|
|
- `01-homepage.png` - Application homepage
|
|
- `02-logged-in.png` - After login
|
|
- `03-project-flow.png` - Project flow view
|
|
- `04-customer-info.png` - Customer information filled
|
|
- `05-geometry.png` - Geometry data entered
|
|
- `06-package-selected.png` - Smart package selected
|
|
- `07-materials-labor.png` - Materials and labor review
|
|
- `08-final-review.png` - Final review before quote
|
|
- `08-quote-generated.png` - Generated quote
|
|
|
|
### Test Results JSON
|
|
Results saved to: `tests/test-results/selenium-screenshots/test_results.json`
|
|
|
|
Example structure:
|
|
```json
|
|
{
|
|
"customer": {
|
|
"customer_name": "Test Tømrerkunde - 20251220-143000",
|
|
"customer_email": "[email protected]",
|
|
"customer_phone": "42 46 81 10",
|
|
"project_description": "Ny terrasse 25 m² med douglasgran"
|
|
},
|
|
"geometry": {
|
|
"area": "25",
|
|
"length": "5",
|
|
"width": "5"
|
|
},
|
|
"pricing": {
|
|
"total_estimated": 45000.00,
|
|
"prices_found": ["45.000 kr", "11.250 kr", ...]
|
|
},
|
|
"realism_check": {
|
|
"passed": 7,
|
|
"total": 7,
|
|
"details": {
|
|
"Customer name": true,
|
|
"Materials (wood)": true,
|
|
"Area (m²)": true,
|
|
"Price (kr)": true,
|
|
"Labor/hours": true,
|
|
"VAT/Moms": true,
|
|
"Company info": true
|
|
}
|
|
},
|
|
"api_verification": {
|
|
"project_id": 54,
|
|
"status": "materials_pending",
|
|
"area": "25.00",
|
|
"materials": 5
|
|
}
|
|
}
|
|
```
|
|
|
|
## Test Configuration
|
|
|
|
### Environment Variables
|
|
```bash
|
|
export BASE_URL=http://localhost:3000
|
|
export API_URL=http://localhost:4031
|
|
```
|
|
|
|
### Timeouts
|
|
Default: 20 seconds for element waits
|
|
Modify in test file:
|
|
```python
|
|
cls.wait = WebDriverWait(cls.driver, 20)
|
|
```
|
|
|
|
### Browser Options
|
|
Configured in `setUpClass`:
|
|
```python
|
|
options.add_argument('--headless') # Headless mode
|
|
options.add_argument('--window-size=1920,1080') # Window size
|
|
options.add_argument('--no-sandbox') # Linux compatibility
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### ChromeDriver Version Mismatch
|
|
```
|
|
Error: This version of ChromeDriver only supports Chrome version X
|
|
```
|
|
**Solution:** Update ChromeDriver to match Chrome version
|
|
|
|
### Server Not Running
|
|
```
|
|
❌ Backend server not running on port 4031
|
|
```
|
|
**Solution:** Start backend server first
|
|
|
|
### Element Not Found
|
|
```
|
|
selenium.common.exceptions.NoSuchElementException
|
|
```
|
|
**Solution:**
|
|
- Increase wait timeout
|
|
- Check element selector
|
|
- Verify React has fully loaded
|
|
|
|
### Login Failed
|
|
**Solution:**
|
|
- Check credentials (default: admin/admin123)
|
|
- Verify auth system is working
|
|
- Check for captcha or rate limiting
|
|
|
|
## Comparison: Selenium vs Playwright
|
|
|
|
### Selenium Advantages
|
|
- ✅ More mature, wider adoption
|
|
- ✅ Better Python integration
|
|
- ✅ More browser support options
|
|
- ✅ Familiar to most testers
|
|
|
|
### Playwright Advantages
|
|
- ✅ Faster execution
|
|
- ✅ Better auto-waiting
|
|
- ✅ Native TypeScript support
|
|
- ✅ Better screenshot/video capture
|
|
- ✅ Multiple browser contexts
|
|
|
|
### Recommendation
|
|
- **Use Selenium** for: Python-heavy workflows, team familiarity
|
|
- **Use Playwright** for: Modern async workflows, better debugging
|
|
|
|
Both are production-ready and well-maintained.
|
|
|
|
## CI/CD Integration
|
|
|
|
### GitHub Actions Example
|
|
```yaml
|
|
name: Selenium UI Tests
|
|
|
|
on: [push, pull_request]
|
|
|
|
jobs:
|
|
test:
|
|
runs-on: ubuntu-latest
|
|
|
|
services:
|
|
postgres:
|
|
image: postgres:13
|
|
env:
|
|
POSTGRES_PASSWORD: postgres
|
|
|
|
steps:
|
|
- uses: actions/checkout@v2
|
|
|
|
- name: Setup Python
|
|
uses: actions/setup-python@v2
|
|
with:
|
|
python-version: '3.9'
|
|
|
|
- name: Install Chrome
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y chromium-browser
|
|
|
|
- name: Install dependencies
|
|
run: |
|
|
pip install selenium requests
|
|
|
|
- name: Start servers
|
|
run: |
|
|
npm install
|
|
npm run start:backend &
|
|
npm run start:frontend &
|
|
sleep 10
|
|
|
|
- name: Run Selenium tests
|
|
run: |
|
|
cd tests/selenium
|
|
python3 carpenter_quote_test.py
|
|
|
|
- name: Upload screenshots
|
|
if: always()
|
|
uses: actions/upload-artifact@v2
|
|
with:
|
|
name: selenium-screenshots
|
|
path: tests/test-results/selenium-screenshots/
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
1. **Always wait for elements**
|
|
```python
|
|
element = self.wait.until(
|
|
EC.presence_of_element_located((By.ID, 'element-id'))
|
|
)
|
|
```
|
|
|
|
2. **Take screenshots on failures**
|
|
- Automatically done in tearDown
|
|
- Manual: `self.screenshot('step-name')`
|
|
|
|
3. **Use descriptive test names**
|
|
```python
|
|
def test_01_navigate_to_app(self):
|
|
def test_02_login(self):
|
|
```
|
|
|
|
4. **Clean up test data**
|
|
- Use unique timestamps
|
|
- Clean database after tests (optional)
|
|
|
|
5. **Handle dynamic content**
|
|
- Wait for React to load
|
|
- Use explicit waits, not sleep()
|
|
|
|
## Support
|
|
|
|
For issues or questions:
|
|
1. Check screenshots in test-results/
|
|
2. Review test output logs
|
|
3. Verify servers are running
|
|
4. Check browser console for errors
|
|
|
|
## License
|
|
|
|
Part of Tilbudgivern project - see root LICENSE file.
|