spanwright
Version:
CLI tool to generate Cloud Spanner E2E testing framework projects with Go database tools and Playwright browser automation
218 lines (193 loc) โข 10.9 kB
Plain Text
# Simplified Spanwright Makefile
# Load environment variables
-include .env
export
# Default values
PROJECT_ID ?= test-project
INSTANCE_ID ?= test-instance
PRIMARY_DB_ID ?= primary-db
SECONDARY_DB_ID ?= secondary-db
DB_COUNT ?= 2
SCENARIO ?= example-01-basic-setup
# Docker settings
DOCKER_IMAGE ?= gcr.io/cloud-spanner-emulator/emulator
DOCKER_CONTAINER_NAME ?= spanner-emulator
DOCKER_SPANNER_PORT ?= 9010
.PHONY: help init clean start stop setup run-all test-e2e
help: ## Show this help
@echo "Spanwright E2E Testing Framework"
@echo "================================"
@echo ""
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(firstword $(MAKEFILE_LIST)) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
init: ## Initialize project and check prerequisites
@echo "๐ Initializing Spanwright project..."
@$(MAKE) check-tools
@$(MAKE) setup-playwright
@echo "โ
Project initialized successfully"
check-tools: ## Check required tools
@echo "๐ Checking required tools..."
@command -v wrench >/dev/null 2>&1 || { echo "โ wrench not found"; exit 1; }
@command -v docker >/dev/null 2>&1 || { echo "โ docker not found"; exit 1; }
@command -v node >/dev/null 2>&1 || { echo "โ node not found"; exit 1; }
@$(MAKE) check-spalidate
@echo "โ
All tools available"
check-spalidate: ## Check spalidate availability
@command -v spalidate >/dev/null 2>&1 || { echo "โ spalidate not found - install from https://github.com/nu0ma/spalidate"; exit 1; }
@echo "โ
spalidate available"
setup-playwright: ## Setup Playwright
@echo "๐ญ Setting up Playwright..."
@npm install
@npx playwright install
@echo "โ
Playwright setup complete"
start: ## Start Spanner emulator
@echo "๐ณ Starting Spanner emulator..."
@if docker ps -a --format '{{.Names}}' | grep -q "^$(DOCKER_CONTAINER_NAME)$$"; then \
echo "๐ฆ Existing container found, restarting..."; \
docker stop $(DOCKER_CONTAINER_NAME) >/dev/null 2>&1 || true; \
docker rm $(DOCKER_CONTAINER_NAME) >/dev/null 2>&1 || true; \
fi
@docker run -d --name $(DOCKER_CONTAINER_NAME) -p $(DOCKER_SPANNER_PORT):9010 $(DOCKER_IMAGE) >/dev/null
@echo "โณ Waiting for emulator to be ready..."
@sleep 15
@echo "๐ Verifying emulator status..."
@if ! docker ps | grep -q $(DOCKER_CONTAINER_NAME); then echo "โ Emulator container not running"; exit 1; fi
@echo "โ
Spanner emulator ready on localhost:$(DOCKER_SPANNER_PORT)"
stop: ## Stop Spanner emulator
@echo "๐ Stopping Spanner emulator..."
@docker stop $(DOCKER_CONTAINER_NAME) 2>/dev/null || true
@docker rm $(DOCKER_CONTAINER_NAME) 2>/dev/null || true
clean: ## Clean up containers and artifacts
@$(MAKE) stop
@echo "๐งน Cleaning build artifacts..."
@rm -rf test-results/ playwright-report/
setup: ## Setup databases and schemas
@echo "๐๏ธ Setting up databases..."
@$(MAKE) start
@$(MAKE) setup-primary
ifeq ($(DB_COUNT),2)
@$(MAKE) setup-secondary
endif
@echo "โ
Database setup complete"
setup-primary: ## Setup primary database
@echo "๐ถ Setting up primary database..."
@echo "๐ก Creating Spanner instance $(INSTANCE_ID)..."
@SPANNER_PROJECT_ID=$(PROJECT_ID) SPANNER_INSTANCE_ID=$(INSTANCE_ID) SPANNER_EMULATOR_HOST=localhost:$(DOCKER_SPANNER_PORT) wrench instance create 2>/dev/null || echo " โน๏ธ Instance $(INSTANCE_ID) already exists or has been created"
@echo "๐๏ธ Creating empty database $(PRIMARY_DB_ID)..."
@mkdir -p ./tmp && echo "-- Empty schema for database creation" > ./tmp/schema.sql
@SPANNER_PROJECT_ID=$(PROJECT_ID) SPANNER_INSTANCE_ID=$(INSTANCE_ID) SPANNER_DATABASE_ID=$(PRIMARY_DB_ID) SPANNER_EMULATOR_HOST=localhost:$(DOCKER_SPANNER_PORT) wrench create --directory="$$(pwd)/tmp" --schema_file=schema.sql 2>/dev/null || echo " โน๏ธ Database $(PRIMARY_DB_ID) already exists or has been created"
@echo "๐ Applying individual schema files from $(PRIMARY_SCHEMA_PATH)..."
@for file in "$(PRIMARY_SCHEMA_PATH)"/*.sql; do \
if [ -f "$$file" ]; then \
echo " ๐ Applying: $$file"; \
SPANNER_PROJECT_ID=$(PROJECT_ID) SPANNER_INSTANCE_ID=$(INSTANCE_ID) SPANNER_DATABASE_ID=$(PRIMARY_DB_ID) SPANNER_EMULATOR_HOST=localhost:$(DOCKER_SPANNER_PORT) wrench apply --ddl="$$file" || { echo "โ Failed to apply: $$file"; exit 1; }; \
fi; \
done
@echo "โ
Schema application completed for primary database"
@echo "๐ง Setting up Go modules..."
@go mod tidy >/dev/null 2>&1
@echo "๐ฑ Seeding primary database..."
@SPANNER_EMULATOR_HOST=localhost:$(DOCKER_SPANNER_PORT) go run cmd/seed-injector/main.go --database-id $(PRIMARY_DB_ID) --fixture-dir "$$(pwd)/scenarios/$(SCENARIO)/fixtures/primary" || { echo "โ Failed to seed primary database"; exit 1; }
@echo "โ
Primary database ready"
setup-secondary: ## Setup secondary database
@echo "โ๏ธ Setting up secondary database..."
@echo "๐๏ธ Creating empty database $(SECONDARY_DB_ID)..."
@mkdir -p ./tmp && echo "-- Empty schema for database creation" > ./tmp/schema.sql
@SPANNER_PROJECT_ID=$(PROJECT_ID) SPANNER_INSTANCE_ID=$(INSTANCE_ID) SPANNER_DATABASE_ID=$(SECONDARY_DB_ID) SPANNER_EMULATOR_HOST=localhost:$(DOCKER_SPANNER_PORT) wrench create --directory="$$(pwd)/tmp" --schema_file=schema.sql 2>/dev/null || echo " โน๏ธ Database $(SECONDARY_DB_ID) already exists or has been created"
@echo "๐ Applying individual schema files from $(SECONDARY_SCHEMA_PATH)..."
@for file in "$(SECONDARY_SCHEMA_PATH)"/*.sql; do \
if [ -f "$$file" ]; then \
echo " ๐ Applying: $$file"; \
SPANNER_PROJECT_ID=$(PROJECT_ID) SPANNER_INSTANCE_ID=$(INSTANCE_ID) SPANNER_DATABASE_ID=$(SECONDARY_DB_ID) SPANNER_EMULATOR_HOST=localhost:$(DOCKER_SPANNER_PORT) wrench apply --ddl="$$file" || { echo "โ Failed to apply: $$file"; exit 1; }; \
fi; \
done
@echo "โ
Schema application completed for secondary database"
@echo "๐ง Setting up Go modules..."
@go mod tidy >/dev/null 2>&1
@echo "๐ฑ Seeding secondary database..."
@SPANNER_EMULATOR_HOST=localhost:$(DOCKER_SPANNER_PORT) go run cmd/seed-injector/main.go --database-id $(SECONDARY_DB_ID) --fixture-dir "$$(pwd)/scenarios/$(SCENARIO)/fixtures/secondary" || { echo "โ Failed to seed secondary database"; exit 1; }
@echo "โ
Secondary database ready"
test-scenario: ## Run specific scenario test
@echo "๐งช Running scenario: $(SCENARIO)"
@echo "๐ Verifying emulator status before tests..."
@if ! docker ps | grep -q $(DOCKER_CONTAINER_NAME); then echo "โ Emulator not running"; exit 1; fi
@echo "๐ญ Starting Playwright tests..."
@SPANNER_EMULATOR_HOST=localhost:$(DOCKER_SPANNER_PORT) \
PROJECT_ID=$(PROJECT_ID) \
INSTANCE_ID=$(INSTANCE_ID) \
PRIMARY_DB_ID=$(PRIMARY_DB_ID) \
SECONDARY_DB_ID=$(SECONDARY_DB_ID) \
DB_COUNT=$(DB_COUNT) \
npx playwright test --grep $(SCENARIO) || { echo "โ Playwright tests failed for $(SCENARIO)"; exit 1; }
run-all: run-all-scenarios ## Alias for run-all-scenarios
run-all-scenarios: ## Run all scenarios
@echo "๐ Running all scenarios..."
@echo "๐ Environment: PROJECT_ID=$(PROJECT_ID), INSTANCE_ID=$(INSTANCE_ID), DB_COUNT=$(DB_COUNT)"
@$(MAKE) setup
@scenarios=$$(ls scenarios/ | grep -E '^(scenario|example)-'); \
if [ -z "$$scenarios" ]; then \
echo "โ No scenarios found in scenarios/ directory"; \
exit 1; \
fi; \
echo "๐ Found scenarios: $$scenarios"; \
for scenario in $$scenarios; do \
echo "โถ๏ธ Running $$scenario"; \
SCENARIO=$$scenario $(MAKE) test-scenario || { echo "โ Failed running scenario $$scenario"; exit 1; }; \
echo "๐ Validating $$scenario database state..."; \
SCENARIO=$$scenario $(MAKE) validate-scenario || { echo "โ Failed validating scenario $$scenario"; exit 1; }; \
echo "โ
Scenario $$scenario completed successfully"; \
done
@echo "โ
All scenarios completed"
test-e2e: ## Run Playwright E2E tests
@npx playwright test
test-report: ## Open test report
@echo "๐ Opening test report..."
@npx playwright show-report
validate-scenario: ## Validate scenario database state
@if [ -z "$(SCENARIO)" ]; then echo "โ SCENARIO required"; exit 1; fi
@echo "๐ Validating scenario databases for $(SCENARIO)..."
@echo "๐ก Checking emulator status..."
@if ! docker ps | grep -q $(DOCKER_CONTAINER_NAME); then echo "โ Emulator not running for validation"; exit 1; fi
@if [ -f "scenarios/$(SCENARIO)/expected-primary.yaml" ]; then \
echo "๐ Validating primary database for $(SCENARIO)..."; \
SPANNER_EMULATOR_HOST=localhost:$(DOCKER_SPANNER_PORT) spalidate --project $(PROJECT_ID) --instance $(INSTANCE_ID) --database $(PRIMARY_DB_ID) --verbose scenarios/$(SCENARIO)/expected-primary.yaml || { echo "โ Primary database validation failed for $(SCENARIO)"; exit 1; }; \
else \
echo "โ ๏ธ No primary validation file found for $(SCENARIO)"; \
fi
ifeq ($(DB_COUNT),2)
@if [ -f "scenarios/$(SCENARIO)/expected-secondary.yaml" ]; then \
echo "๐ Validating secondary database for $(SCENARIO)..."; \
SPANNER_EMULATOR_HOST=localhost:$(DOCKER_SPANNER_PORT) spalidate --project $(PROJECT_ID) --instance $(INSTANCE_ID) --database $(SECONDARY_DB_ID) --verbose scenarios/$(SCENARIO)/expected-secondary.yaml || { echo "โ Secondary database validation failed for $(SCENARIO)"; exit 1; }; \
else \
echo "โ ๏ธ No secondary validation file found for $(SCENARIO)"; \
fi
endif
@echo "โ
Database validation completed for $(SCENARIO)"
validate-db: ## Validate all databases for current scenario
@$(MAKE) validate-scenario
new-scenario: ## Create new scenario (SCENARIO=name required)
@if [ -z "$(SCENARIO)" ]; then echo "โ SCENARIO required"; exit 1; fi
@echo "๐ Creating scenario: $(SCENARIO)"
@mkdir -p scenarios/$(SCENARIO)/fixtures scenarios/$(SCENARIO)/tests
@cp expected-primary.yaml.template scenarios/$(SCENARIO)/expected-primary.yaml 2>/dev/null || echo "โ ๏ธ No primary template found"
ifeq ($(DB_COUNT),2)
@cp expected-secondary.yaml.template scenarios/$(SCENARIO)/expected-secondary.yaml 2>/dev/null || echo "โ ๏ธ No secondary template found"
endif
@echo "โ
Scenario $(SCENARIO) created"
validate: ## Validate configuration and schemas
@echo "๐ Validating configuration..."
@test -f ".env" || { echo "โ .env file missing"; exit 1; }
@test -n "$(PRIMARY_SCHEMA_PATH)" || { echo "โ PRIMARY_SCHEMA_PATH not set"; exit 1; }
@test -d "$(PRIMARY_SCHEMA_PATH)" || { echo "โ Primary schema directory not found"; exit 1; }
ifeq ($(DB_COUNT),2)
@test -n "$(SECONDARY_SCHEMA_PATH)" || { echo "โ SECONDARY_SCHEMA_PATH not set"; exit 1; }
@test -d "$(SECONDARY_SCHEMA_PATH)" || { echo "โ Secondary schema directory not found"; exit 1; }
endif
@echo "โ
Configuration valid"
build: ## Build Go tools
@echo "๐จ Building Go tools..."
@go mod tidy
@go build -o bin/seed-injector cmd/seed-injector/main.go
@echo "โ
Build complete"
dev: ## Development mode - setup and watch
@$(MAKE) setup
@echo "๐ Development mode - run 'make test-e2e' to test"