mirror of https://github.com/coder/coder.git
chore(site): add remote playwright support and script (#10445)
This commit is contained in:
parent
ed7e43b54c
commit
e71c53d4d0
|
@ -217,6 +217,23 @@ to test if the page is being rendered correctly, you should consider using the
|
||||||
> ℹ️ For scenarios where you need to be authenticated, you can use
|
> ℹ️ For scenarios where you need to be authenticated, you can use
|
||||||
> `test.use({ storageState: getStatePath("authState") })`.
|
> `test.use({ storageState: getStatePath("authState") })`.
|
||||||
|
|
||||||
|
For ease of debugging, it's possible to run a Playwright test in headful mode
|
||||||
|
running a Playwright server on your local machine, and executing the test inside
|
||||||
|
your workspace.
|
||||||
|
|
||||||
|
You can either run `scripts/remote_playwright.sh` from `coder/coder` on your
|
||||||
|
local machine, or execute the following command if you don't have the repo
|
||||||
|
available:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash <(curl -sSL https://raw.githubusercontent.com/coder/coder/main/scripts/remote_playwright.sh) [workspace]
|
||||||
|
```
|
||||||
|
|
||||||
|
The `scripts/remote_playwright.sh` script will start a Playwright server on your
|
||||||
|
local machine and forward the necessary ports to your workspace. At the end of
|
||||||
|
the script, you will land _inside_ your workspace with environment variables set
|
||||||
|
so you can simply execute the test (`pnpm run playwright:test`).
|
||||||
|
|
||||||
### Integration
|
### Integration
|
||||||
|
|
||||||
Test user interactions like "Click in a button shows a dialog", "Submit the form
|
Test user interactions like "Click in a button shows a dialog", "Submit the form
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
workspace=${1:-}
|
||||||
|
coder_repo=${2:-.}
|
||||||
|
port=${3:-3000}
|
||||||
|
|
||||||
|
if [[ -z "${workspace}" ]]; then
|
||||||
|
echo "Usage: $0 <workspace> [workspace coder/coder dir] [e2e port]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
main() {
|
||||||
|
# Check the Playwright version from the workspace so we have a 1-to-1 match
|
||||||
|
# between the current branch and what we're going to run locally. This is
|
||||||
|
# necessary because Playwright uses their own protocol for communicating
|
||||||
|
# between the server and client, and the protocol changes between versions.
|
||||||
|
echo "Checking Playwright version from \"${workspace}\"..."
|
||||||
|
# shellcheck disable=SC2029 # This is intended to expand client-side.
|
||||||
|
playwright_version="$(ssh "coder.${workspace}" "cat '${coder_repo}'/site/pnpm-lock.yaml | grep '^ /@playwright/test@' | cut -d '@' -f 3 | tr -d ':'")"
|
||||||
|
|
||||||
|
echo "Found Playwright version ${playwright_version}..."
|
||||||
|
|
||||||
|
# Let's store it in cache because, why not, this is ephemeral.
|
||||||
|
dest=~/.cache/coder-remote-playwright
|
||||||
|
echo "Initializing Playwright server in ${dest}..."
|
||||||
|
mkdir -p "${dest}"
|
||||||
|
cd "${dest}"
|
||||||
|
echo '{"dependencies":{"@playwright/test":"'"${playwright_version}"'"}}' >package.json
|
||||||
|
cat <<-EOF >server.mjs
|
||||||
|
import { chromium } from "@playwright/test";
|
||||||
|
|
||||||
|
const server = await chromium.launchServer({ headless: false });
|
||||||
|
console.log(server.wsEndpoint());
|
||||||
|
EOF
|
||||||
|
|
||||||
|
npm_cmd=npm
|
||||||
|
if command -v pnpm >/dev/null; then
|
||||||
|
npm_cmd=pnpm
|
||||||
|
fi
|
||||||
|
echo "Running \"${npm_cmd} install\" to ensure local and remote are up-to-date..."
|
||||||
|
"${npm_cmd}" install
|
||||||
|
|
||||||
|
echo "Running \"${npm_cmd} exec playwright install\" for browser binaries..."
|
||||||
|
"${npm_cmd}" exec playwright install
|
||||||
|
|
||||||
|
playwright_out="$(mktemp -t playwright_server_out.XXXXXX)"
|
||||||
|
|
||||||
|
rm "${playwright_out}"
|
||||||
|
mkfifo "${playwright_out}"
|
||||||
|
exec 3<>"${playwright_out}"
|
||||||
|
|
||||||
|
echo "Starting Playwright server..."
|
||||||
|
${npm_cmd} exec node server.mjs 1>&3 &
|
||||||
|
playwright_pid=$!
|
||||||
|
|
||||||
|
trap '
|
||||||
|
kill -INT ${playwright_pid}
|
||||||
|
exec 3>&-
|
||||||
|
rm "${playwright_out}"
|
||||||
|
wait ${playwright_pid}
|
||||||
|
' EXIT
|
||||||
|
|
||||||
|
echo "Waiting for Playwright to start..."
|
||||||
|
read -r ws_endpoint <&3
|
||||||
|
if [[ ${ws_endpoint} != ws://* ]]; then
|
||||||
|
echo "Playwright failed to start."
|
||||||
|
echo "${ws_endpoint}"
|
||||||
|
cat "${playwright_out}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Playwright started at ${ws_endpoint}"
|
||||||
|
|
||||||
|
ws_port=${ws_endpoint##*:}
|
||||||
|
ws_port=${ws_port%/*}
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Starting SSH tunnel, run test via \"pnpm run playwright:test\"..."
|
||||||
|
# shellcheck disable=SC2029 # This is intended to expand client-side.
|
||||||
|
ssh -t -R "${ws_port}:127.0.0.1:${ws_port}" -L "${port}:127.0.0.1:${port}" coder."${workspace}" "export CODER_E2E_PORT='${port}'; export CODER_E2E_WS_ENDPOINT='${ws_endpoint}'; [[ -d '${coder_repo}/site' ]] && cd '${coder_repo}/site'; exec \"\$(grep \"\${USER}\": /etc/passwd | cut -d: -f7)\" -i -l"
|
||||||
|
}
|
||||||
|
|
||||||
|
main
|
|
@ -6,6 +6,8 @@ export const port = process.env.CODER_E2E_PORT
|
||||||
? Number(process.env.CODER_E2E_PORT)
|
? Number(process.env.CODER_E2E_PORT)
|
||||||
: defaultPort;
|
: defaultPort;
|
||||||
|
|
||||||
|
export const wsEndpoint = process.env.CODER_E2E_WS_ENDPOINT;
|
||||||
|
|
||||||
const coderMain = path.join(__dirname, "../../enterprise/cmd/coder");
|
const coderMain = path.join(__dirname, "../../enterprise/cmd/coder");
|
||||||
|
|
||||||
export const STORAGE_STATE = path.join(__dirname, ".auth.json");
|
export const STORAGE_STATE = path.join(__dirname, ".auth.json");
|
||||||
|
@ -34,9 +36,17 @@ export default defineConfig({
|
||||||
use: {
|
use: {
|
||||||
baseURL: `http://localhost:${port}`,
|
baseURL: `http://localhost:${port}`,
|
||||||
video: "retain-on-failure",
|
video: "retain-on-failure",
|
||||||
launchOptions: {
|
...(wsEndpoint
|
||||||
args: ["--disable-webgl"],
|
? {
|
||||||
},
|
connectOptions: {
|
||||||
|
wsEndpoint: wsEndpoint,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
launchOptions: {
|
||||||
|
args: ["--disable-webgl"],
|
||||||
|
},
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
webServer: {
|
webServer: {
|
||||||
url: `http://localhost:${port}/api/v2/deployment/config`,
|
url: `http://localhost:${port}/api/v2/deployment/config`,
|
||||||
|
|
Loading…
Reference in New Issue