Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What: There are no comments or documentation included in this configuration file which makes it difficult to understand the purpose of the permissions set.

Why: Providing context or a brief description for file permissions can make it easier for other developers to understand why specific permissions were granted or denied. This also aids in future maintenance and onboarding of new developers.

How: Add a comment at the top of the file explaining the purpose of these permissions and any relevant context. For example:

// Configuration for user permissions in Bash commands. Only minimal required permissions should be granted based on the user’s role.

"permissions": {
"allow": [
"Bash(find:*)",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What: Consider the permissions defined in this configuration file. Allowing unrestricted access to commands like Bash(find:), Bash(chmod:) can lead to serious security risks, as they could potentially allow unauthorized users to manipulate files and directories.

Why: This aspect is crucial because improperly configured permissions can expose your system to attacks or misuse, especially in environments where multiple users may have access. It's essential to practice the principle of least privilege, granting only the necessary permissions that users need to perform their tasks without enabling dangerous commands.

How: Mitigate this risk by specifying more restrictive permissions. For example, only allow permissions that are absolutely necessary for the tasks intended. Instead of allowing all commands under Bash, you might restrict it to specific commands that are safer. You should also consider auditing what commands are needed and possibly quota-limiting where needed.

"Bash(chmod:*)",
"Bash(mkdir:*)",
"Bash(npm install:*)",
"Bash(composer require:*)",
"Bash(bash:*)",
"Bash(composer test:*)"
],
"deny": []
}
}
169 changes: 169 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
name: Tests

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]

jobs:
phpunit:
runs-on: ubuntu-latest
strategy:
matrix:
php: [7.4, 8.0, 8.1, 8.2]
wordpress: [latest]
include:
- php: 7.4
wordpress: 5.9
- php: 8.2
wordpress: trunk

services:
mysql:
image: mysql:5.7
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: wordpress_test
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3

steps:
- uses: actions/checkout@v3

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: mbstring, xml, ctype, iconv, intl, pdo_sqlite, mysql
coverage: xdebug

- name: Get composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT

- name: Cache dependencies
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-

- name: Install dependencies
run: composer install --prefer-dist --no-progress

- name: Install WP Tests
run: bash bin/install-wp-tests.sh wordpress_test root root 127.0.0.1:3306 ${{ matrix.wordpress }} true

- name: Run PHPUnit tests
run: composer test

e2e-jest:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Setup WordPress Environment
run: npm run env:start

- name: Run E2E tests
run: npm run test:e2e:ci

- name: Upload screenshots on failure
if: failure()
uses: actions/upload-artifact@v3
with:
name: e2e-screenshots
path: tests/e2e/screenshots

e2e-playwright:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Install Playwright Browsers
run: npx playwright install --with-deps

- name: Setup WordPress Environment
run: npm run env:start

- name: Run Playwright tests
run: npm run test:e2e:playwright

- name: Upload Playwright Report
if: always()
uses: actions/upload-artifact@v3
with:
name: playwright-report
path: playwright-report/
retention-days: 30

lint:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.0

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'

- name: Install PHP dependencies
run: composer install --prefer-dist --no-progress

- name: Install JS dependencies
run: npm ci

- name: Run PHP linting
run: composer lint

- name: Run JS linting
run: npm run lint:js

- name: Run CSS linting
run: npm run lint:css

phpstan:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.0

- name: Install dependencies
run: composer install --prefer-dist --no-progress

- name: Run PHPStan
run: composer phpstan
1 change: 1 addition & 0 deletions .phpunit.result.cache
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"version":1,"defects":{"Test_Plugin_Loading::test_admin_class_exists":3,"Test_Plugin_Loading::test_singleton_instance":4,"Test_Plugin_Loading::test_hooks_registered":3,"Test_Plugin_Loading::test_register_post_type":4,"Test_Plugin_Loading::test_shortcode_registered":3},"times":{"Test_Plugin_Loading::test_constants_defined":0.001,"Test_Plugin_Loading::test_version_format":0,"Test_Plugin_Loading::test_main_class_exists":0,"Test_Plugin_Loading::test_admin_class_exists":0,"Test_Plugin_Loading::test_singleton_instance":0,"Test_Plugin_Loading::test_hooks_registered":0,"Test_Plugin_Loading::test_register_post_type":0,"Test_Plugin_Loading::test_shortcode_registered":0}}
133 changes: 133 additions & 0 deletions TESTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Header Footer Elementor - Testing Quick Start Guide

## Prerequisites

- **PHP**: 7.4 or higher
- **Node.js**: 18.x or higher
- **Composer**: Installed globally
- **Local Sites**: Running (for integration tests)

## Initial Setup

```bash
# Install PHP dependencies
composer install

# Install Node dependencies
npm install
```

## Running Tests

### 1. PHPUnit Tests (Mock - Recommended)

**No database required, works offline**

```bash
# Run all mock tests
composer test:mock

# Run with code coverage
composer test:mock:coverage
```

### 2. E2E Tests - Playwright (Modern)

```bash
# Start WordPress environment
npm run env:start

# Run all Playwright tests
npm run test:e2e:playwright

# Run in headed mode (see browser)
npm run test:e2e:playwright:headed

# Run in UI mode (interactive)
npm run test:e2e:playwright:ui

# View test report
npm run test:e2e:playwright:report
```

### 3. E2E Tests - Jest/Puppeteer (Legacy)

```bash
# Start WordPress environment
npm run env:start

# Run all Jest E2E tests
npm run test:e2e

# Run in interactive mode
npm run test:e2e:interactive

# Debug mode
npm run test:e2e:debug
```

## Quick Commands Reference

| Command | Description |
|---------|-------------|
| `composer test:mock` | Run PHPUnit tests without database |
| `npm run test:e2e:playwright` | Run Playwright E2E tests |
| `npm run test:e2e` | Run Jest/Puppeteer E2E tests |
| `npm run env:start` | Start WordPress test environment |
| `npm run env:stop` | Stop WordPress test environment |
| `composer lint` | Run PHP code standards check |
| `npm run lint:js` | Run JavaScript linting |

## Writing New Tests

### PHPUnit Tests
Create files in `tests/php/mock/` prefixed with `test-`:
```php
class Test_My_Feature extends HFE_Mock_Test_Case {
public function test_something() {
$this->assertTrue( true );
}
}
```

### Playwright E2E Tests
Create files in `tests/e2e/playwright/` ending with `.spec.js`:
```javascript
const { test, expect } = require('@playwright/test');

test('my test', async ({ page }) => {
await page.goto('/wp-admin/');
// Your test code
});
```

## Troubleshooting

### PHPUnit Issues
- If database errors occur, use `composer test:mock` instead
- For coverage reports, ensure Xdebug is installed

### E2E Test Issues
- Ensure WordPress environment is running: `npm run env:start`
- Default test URL: http://localhost:9091
- Clear environment: `npm run env:reset-site`

### Local Sites Specific
- Mock tests (`composer test:mock`) work best with Local Sites
- No database connection required for mock tests
- E2E tests require the WordPress environment to be running

## CI/CD

Tests automatically run on GitHub Actions for:
- Pull requests
- Pushes to main/develop branches
- Multiple PHP versions (7.4, 8.0, 8.1, 8.2)
- Both PHPUnit and E2E tests

## Need Help?

- Detailed documentation: `tests/README.md`
- PHPUnit config: `phpunit-mock.xml`
- Playwright config: `playwright.config.js`
- Jest config: `tests/e2e/jest.config.js`
Loading