$ErrorActionPreference = 'Stop' $LabRoot = Split-Path -Parent (Split-Path -Parent $PSCommandPath) $WorkspaceRoot = Split-Path -Parent (Split-Path -Parent $LabRoot) $ConfigPath = Join-Path $LabRoot 'config\environments.json' $GeneratedRoot = Join-Path $LabRoot 'generated' $ResultsRoot = Join-Path $LabRoot 'results' $PluginSource = Join-Path $WorkspaceRoot 'plugins\bible-reference-tooltips' $PluginSlug = 'bible-reference-tooltips' $ExpectedPluginVersion = '1.1.6' function Get-TestLabEnvironments { Get-Content -LiteralPath $ConfigPath -Raw | ConvertFrom-Json } function Get-TestLabEnvironment { param([Parameter(Mandatory)][string]$Name) $envs = Get-TestLabEnvironments $selected = $envs | Where-Object { $_.name -eq $Name } | Select-Object -First 1 if (-not $selected) { throw "Unknown environment '$Name'. Available: $($envs.name -join ', ')" } return $selected } function Convert-ToComposePath { param([Parameter(Mandatory)][string]$Path) return ($Path -replace '\\', '/') } function Ensure-TestLabDirectories { New-Item -ItemType Directory -Force -Path $GeneratedRoot, $ResultsRoot | Out-Null } function Get-EnvDir { param([Parameter(Mandatory)][string]$Name) return Join-Path $GeneratedRoot $Name } function Get-ResultFile { param([Parameter(Mandatory)][string]$Name) return Join-Path $ResultsRoot "$Name.json" } function Write-ComposeFile { param([Parameter(Mandatory)]$Environment) Ensure-TestLabDirectories $envDir = Get-EnvDir $Environment.name New-Item -ItemType Directory -Force -Path $envDir | Out-Null $pluginPath = Convert-ToComposePath $PluginSource $compose = @" services: db: image: $($Environment.dbImage) environment: MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress MYSQL_ROOT_PASSWORD: rootpass healthcheck: test: ["CMD", "mariadb-admin", "ping", "-h", "localhost", "-uroot", "-prootpass"] interval: 5s timeout: 5s retries: 30 volumes: - db_data:/var/lib/mysql wordpress: image: $($Environment.wordpressImage) depends_on: db: condition: service_healthy ports: - "$($Environment.hostPort):80" environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress WORDPRESS_DB_NAME: wordpress WORDPRESS_DEBUG: "1" volumes: - wp_data:/var/www/html - ${pluginPath}:/var/www/html/wp-content/plugins/$PluginSlug volumes: db_data: wp_data: "@ Set-Content -LiteralPath (Join-Path $envDir 'compose.yml') -Value $compose -Encoding UTF8 } function Invoke-Compose { param( [Parameter(Mandatory)]$Environment, [Parameter(Mandatory)][string[]]$Arguments ) $envDir = Get-EnvDir $Environment.name docker compose -p "wptest-$($Environment.name)" -f (Join-Path $envDir 'compose.yml') @Arguments if ($LASTEXITCODE -ne 0) { throw "docker compose failed with exit code ${LASTEXITCODE}: $($Arguments -join ' ')" } } function Invoke-WpCli { param( [Parameter(Mandatory)]$Environment, [Parameter(Mandatory)][string]$Command ) Invoke-Compose $Environment @('exec', '-T', '-u', '33', 'wordpress', 'bash', '-lc', $Command) } function Invoke-WpCliRoot { param( [Parameter(Mandatory)]$Environment, [Parameter(Mandatory)][string]$Command ) Invoke-Compose $Environment @('exec', '-T', 'wordpress', 'bash', '-lc', $Command) } function Write-ContainerPhpFile { param( [Parameter(Mandatory)]$Environment, [Parameter(Mandatory)][string]$ContainerPath, [Parameter(Mandatory)][string]$Content ) $encoded = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($Content)) Invoke-WpCliRoot $Environment "rm -f '$ContainerPath' && printf '%s' '$encoded' | base64 -d > '$ContainerPath' && chown www-data:www-data '$ContainerPath'" | Out-Null } function Write-ContainerTextFile { param( [Parameter(Mandatory)]$Environment, [Parameter(Mandatory)][string]$ContainerPath, [Parameter(Mandatory)][string]$Content, [string]$Mode = '0644' ) $encoded = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($Content)) Invoke-WpCliRoot $Environment "rm -f '$ContainerPath' && printf '%s' '$encoded' | base64 -d > '$ContainerPath' && chmod '$Mode' '$ContainerPath' && chown www-data:www-data '$ContainerPath'" | Out-Null }