修改使install.sh脚本兼容DoD,修复一些错误,增加了一些关键位置的截图和超时判断
This commit is contained in:
@@ -11,22 +11,22 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Clean
|
||||
run: |
|
||||
public/assets/install.sh clean
|
||||
docker volume rm devstar_data_vol || true
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: start DevStar Container
|
||||
run: |
|
||||
# 替换数据卷路径
|
||||
sed -i 's|~/devstar_data|devstar_data_vol|g' public/assets/install.sh
|
||||
# 启动容器
|
||||
public/assets/install.sh start --image=devstar-studio:latest
|
||||
LOGS=$(public/assets/install.sh start \
|
||||
--port=8082 \
|
||||
--ssh-port=2224 \
|
||||
--data-dir=/tmp/devstar_ci \
|
||||
--image=devstar-studio:latest 2>&1)
|
||||
echo "$LOGS"
|
||||
TARGET_URL=$(echo "$LOGS" | grep -o 'http://[^ ]*' | tail -1 | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g")
|
||||
echo "TARGET_URL=$TARGET_URL" >> $GITHUB_ENV
|
||||
- name: Run E2E Tests
|
||||
run: |
|
||||
make e2e-test TARGET_URL="http://localhost:80"
|
||||
make e2e-test TARGET_URL="$TARGET_URL"
|
||||
env:
|
||||
GITEA_I_AM_BEING_UNSAFE_RUNNING_AS_ROOT: "true"
|
||||
- name: 4. Upload E2E Test Report
|
||||
|
||||
@@ -15,7 +15,7 @@ const config: PlaywrightTestConfig = {
|
||||
forbidOnly: Boolean(env.CI),
|
||||
retries: env.CI ? 2 : 0,
|
||||
|
||||
reporter: env.CI ? 'list' : [['list'], ['html', {
|
||||
reporter: [['html', {
|
||||
outputFolder: 'playwright-report/html',
|
||||
open: 'never'
|
||||
}]],
|
||||
|
||||
@@ -2,14 +2,13 @@
|
||||
# Copyright 2024 Mengning Software All rights reserved.
|
||||
|
||||
# 默认值
|
||||
NAME=DevStar-Studio
|
||||
NAME="DevStar-Studio-$(date +%Y%m%d-%H-%M-%S)"
|
||||
IMAGE_REGISTRY_USER=mengning997
|
||||
IMAGE_NAME=devstar-studio
|
||||
VERSION=latest # DevStar Studio的默认版本为最新版本
|
||||
PORT=80 # 设置端口默认值为 80
|
||||
SSH_PORT=2222 # 设置ssh默认端口号2222
|
||||
DATA_DIR=${HOME}/devstar_data
|
||||
APP_INI=${DATA_DIR}/app.ini
|
||||
|
||||
# 错误处理函数
|
||||
error_handler() {
|
||||
@@ -111,25 +110,30 @@ function start {
|
||||
mkdir -p $DATA_DIR
|
||||
sudo chown 1000:1000 $DATA_DIR
|
||||
sudo chmod 666 /var/run/docker.sock
|
||||
if [ ! -f "$APP_INI" ]; then
|
||||
DOMAIN_NAME=$(hostname -I | awk '{print $1}')
|
||||
if [[ -n "$CI" ]]; then
|
||||
echo "检测到 CI 环境,正在获取网关 IP..."
|
||||
DOMAIN_NAME=$(ip route show | grep default | awk '{print $3}')
|
||||
else
|
||||
#本地环境不做变化
|
||||
DOMAIN_NAME=$(hostname -I | awk '{print $1}')
|
||||
fi
|
||||
if [ ! -f "${DATA_DIR}/app.ini" ]; then
|
||||
echo "DOMAIN_NAME=$DOMAIN_NAME"
|
||||
else
|
||||
# 读取 DOMAIN 值
|
||||
DOMAIN_NAME=$(grep -E '^\s*DOMAIN\s*=' "$APP_INI" | cut -d'=' -f2 | xargs)
|
||||
DOMAIN_NAME_APP_INI=$(grep -E '^\s*DOMAIN\s*=' "${DATA_DIR}/app.ini" | cut -d'=' -f2 | xargs)
|
||||
# 检查是否成功读取到值
|
||||
if [[ -z "$DOMAIN_NAME" ]]; then
|
||||
DOMAIN_NAME="localhost"
|
||||
if [[ -n "$DOMAIN_NAME_APP_INI" ]]; then
|
||||
DOMAIN_NAME=$DOMAIN_NAME_APP_INI
|
||||
fi
|
||||
echo "DOMAIN_NAME=$DOMAIN_NAME"
|
||||
fi
|
||||
# 启动devstar-studio容器
|
||||
stop
|
||||
if [[ -z "$IMAGE_STR" ]]; then
|
||||
IMAGE_STR="$IMAGE_REGISTRY_USER/$IMAGE_NAME:$VERSION"
|
||||
fi
|
||||
echo "image=$IMAGE_STR"
|
||||
sudo docker run --restart=always --name $NAME -d -p $PORT:3000 -p $SSH_PORT:$SSH_PORT -v /var/run/docker.sock:/var/run/docker.sock -v ~/devstar_data:/var/lib/gitea -v ~/devstar_data:/etc/gitea $IMAGE_STR
|
||||
sudo docker run --restart=always --name $NAME -d -p $PORT:3000 -p $SSH_PORT:$SSH_PORT -v /var/run/docker.sock:/var/run/docker.sock -v ${DATA_DIR}:/var/lib/gitea -v ${DATA_DIR}:/etc/gitea $IMAGE_STR
|
||||
# 打开 `http://localhost:8080` 完成安装。
|
||||
success "-------------------------------------------------------"
|
||||
success "DevStar started in http://$DOMAIN_NAME:$PORT successfully!"
|
||||
@@ -139,30 +143,37 @@ function start {
|
||||
|
||||
# Function to stop
|
||||
function stop {
|
||||
if [ $(docker ps -a --filter "name=^/${NAME}$" -q | wc -l) -gt 0 ]; then
|
||||
sudo docker stop $NAME && sudo docker rm -f $NAME
|
||||
fi
|
||||
if [ $(docker ps -a --filter "name=^/devstar-studio$" -q | wc -l) -gt 0 ]; then
|
||||
sudo docker stop devstar-studio && sudo docker rm -f devstar-studio
|
||||
if [ $(docker ps -a --filter "name=^/DevStar-Studio.*|devstar-studio.*" -q | wc -l) -gt 0 ]; then
|
||||
sudo docker stop $(docker ps -a --filter "name=^/DevStar-Studio.*|devstar-studio.*" -q) && \
|
||||
sudo docker rm -f $(docker ps -a --filter "name=^/DevStar-Studio.*|devstar-studio.*" -q)
|
||||
fi
|
||||
if [ $(docker ps -a --filter "name=^/webterminal-" -q | wc -l) -gt 0 ]; then
|
||||
sudo docker stop $(docker ps -a --filter "name=^/webterminal-" -q) && sudo docker rm -f $(docker ps -a --filter "name=^/webterminal-" -q)
|
||||
fi
|
||||
if [ $(docker ps -a --filter "name=^/runner-" -q | wc -l) -gt 0 ]; then
|
||||
sudo docker stop $(docker ps -a --filter "name=^/runner-" -q) && sudo docker rm -f $(docker ps -a --filter "name=^/runner-" -q)
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to logs
|
||||
function logs {
|
||||
# 查看devstar-studio容器的运行日志
|
||||
sudo docker logs $NAME
|
||||
sudo docker ps -a --filter "name=^/DevStar-Studio.*|devstar-studio.*" --format "table {{.ID}}\t{{.Names}}" | tail -n +2 | while read container_id container_name; do
|
||||
echo "=== 容器日志: $container_name (ID: $container_id) ==="
|
||||
sudo docker logs "$container_id"
|
||||
done
|
||||
}
|
||||
|
||||
# Function to clean
|
||||
function clean {
|
||||
stop
|
||||
rm -rf $DATA_DIR
|
||||
read -p "警告:即将永久删除目录 $DATA_DIR,此操作不可恢复!请输入 'YES' 确认: " confirm
|
||||
if [[ "$confirm" == "YES" ]]; then
|
||||
rm -rf "$DATA_DIR"
|
||||
echo "目录已删除"
|
||||
else
|
||||
echo "操作已取消"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to usage help
|
||||
@@ -173,6 +184,7 @@ function usage {
|
||||
success " start Start DevStar Studio"
|
||||
success " --port=<arg> Specify the port number (default port is 80)"
|
||||
success " --ssh-port=<arg> Specify the ssh-port number (default ssh-port is 2222)"
|
||||
success " --data-dir=<arg> Specify the data directory (default data directory is ~/devstar_data)"
|
||||
success " --version=<arg> Specify the DevStar Studio Image Version (default verson is latest)"
|
||||
success " --image=<arg> Specify the DevStar Studio Image example: devstar-studio:latest "
|
||||
success " stop Stop the running DevStar Studio"
|
||||
@@ -188,7 +200,7 @@ case "$1" in
|
||||
usage
|
||||
;;
|
||||
start)
|
||||
ARGS=$(getopt --long port::,ssh-port::,version::,image:: -- "$@")
|
||||
ARGS=$(getopt --long port::,ssh-port::,data-dir::,version::,image:: -- "$@")
|
||||
if [ $? -ne 0 ]; then
|
||||
failure "ARGS ERROR!"
|
||||
exit 1
|
||||
@@ -205,6 +217,10 @@ case "$1" in
|
||||
SSH_PORT="$2"
|
||||
echo "The SSH_Port is: $SSH_PORT"
|
||||
shift 2 ;;
|
||||
--data-dir)
|
||||
DATA_DIR="$2"
|
||||
echo "The SSH_Port is: $DATA_DIR"
|
||||
shift 2 ;;
|
||||
--version)
|
||||
VERSION="$2"
|
||||
echo "The DevStar Studio Image Version is: $VERSION"
|
||||
@@ -246,5 +262,4 @@ case "$1" in
|
||||
devstar help
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
esac
|
||||
@@ -31,7 +31,7 @@ async function globalSetup(config: FullConfig) {
|
||||
await page.getByRole('textbox', { name: '邮箱地址' }).fill('ilovcatlyn750314@gmail.com');
|
||||
await page.getByRole('textbox', { name: '管理员密码', exact: true }).fill('12345678');
|
||||
await page.getByRole('textbox', { name: '确认密码' }).fill('12345678');
|
||||
await page.getByRole('button', { name: '立即安装'}).click();
|
||||
await page.getByRole('button', { name: '立即安装'}).click({ timeout: 50000 });
|
||||
console.log("安装中,请耐心等待");
|
||||
await page.waitForTimeout(90000);
|
||||
} catch (error) {
|
||||
|
||||
@@ -3,27 +3,18 @@
|
||||
# 它会处理所有清理、权限、拉取和执行工作
|
||||
# 任何命令失败立即退出
|
||||
set -e
|
||||
|
||||
# 获取脚本所在目录和项目根目录,test/e2e和devstar项目根目录
|
||||
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
PROJECT_ROOT=$( cd -- "$SCRIPT_DIR/../.." &> /dev/null && pwd )
|
||||
|
||||
# 导出当前用户 ID,防止 Docker 生成 root 权限文件
|
||||
export CURRENT_UID=$(id -u)
|
||||
export CURRENT_GID=$(id -g)
|
||||
# 切换到项目根目录
|
||||
cd "$PROJECT_ROOT"
|
||||
echo "===== [1/3] 清理旧的测试环境... ====="
|
||||
#删除旧的e2e-runner
|
||||
if [ "$(docker ps -aq -f name=e2e-test-runner-container)" ]; then
|
||||
docker rm -f e2e-test-runner-container
|
||||
fi
|
||||
#清理旧的构建缓存
|
||||
docker image prune -f
|
||||
#清理并重建报告和数据目录
|
||||
rm -rf ./tests/e2e/reports ./tests/e2e/test-data
|
||||
mkdir -p ./tests/e2e/reports/html ./tests/e2e/test-data/devstar_data
|
||||
#赋予目录权限,防止挂载后容器无权写入
|
||||
chmod -R 777 ./tests/e2e/reports
|
||||
#这里添加的代码是因为需要执行npm install,我们以当前用户启动测试容器,避免root权限冲突,所以先预构建文件夹,也作为缓存,缓存npm install.
|
||||
echo "处理 node_modules 权限..."
|
||||
@@ -39,8 +30,6 @@ echo "清理完成。"
|
||||
echo ""
|
||||
|
||||
echo "===== [2/3] 准备环境变量... ====="
|
||||
# 检查从 Makefile 传来的 TARGET_URL 变量是否为空
|
||||
echo " 检查devstar位置:TARGET_URL"
|
||||
export DEVSTAR_URL=$TARGET_URL
|
||||
export E2E_MODE="url"
|
||||
if [ -n "$CI" ] || [ "$CI" = "true" ]; then
|
||||
@@ -68,7 +57,6 @@ set +e
|
||||
|
||||
docker run -d --rm --init --ipc=host \
|
||||
--name e2e-test-runner-container \
|
||||
--network host \
|
||||
-u "root" \
|
||||
-e DEVSTAR_URL="$DEVSTAR_URL" \
|
||||
-e E2E_SKIP_INSTALL="$E2E_SKIP_INSTALL" \
|
||||
@@ -80,7 +68,6 @@ docker run -d --rm --init --ipc=host \
|
||||
-e HOME=/tmp \
|
||||
-w /app \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v "$(pwd)/tests/e2e/reports:/app/playwright-report" \
|
||||
mcr.microsoft.com/playwright:v1.53.2-jammy \
|
||||
tail -f /dev/null
|
||||
echo "容器已启动,正在使用 docker cp 注入代码..."
|
||||
@@ -96,11 +83,11 @@ docker exec e2e-test-runner-container bash -c "
|
||||
npm install --no-package-lock
|
||||
|
||||
echo '依赖安装完成,开始测试...'
|
||||
PLAYWRIGHT_HTML_REPORT=/app/playwright-report npx playwright test
|
||||
npx playwright test
|
||||
"
|
||||
# 捕获 test-runner 的退出码
|
||||
EXIT_CODE=$?
|
||||
set -e
|
||||
docker cp e2e-test-runner-container:/app/playwright-report/. tests/e2e/reports/html-report/
|
||||
docker rm -f e2e-test-runner-container
|
||||
echo "========================================"
|
||||
if [ $EXIT_CODE -eq 0 ]; then
|
||||
@@ -109,14 +96,13 @@ else
|
||||
echo "测试执行失败!"
|
||||
fi
|
||||
echo "========================================"
|
||||
REPORT_DIR="./tests/e2e/reports"
|
||||
if [ -f "$REPORT_DIR/html/index.html" ]; then
|
||||
echo "HTML 报告已生成: $REPORT_DIR//html/index.html"
|
||||
REPORT_DIR="./tests/e2e/reports/"
|
||||
if [ -f "$REPORT_DIR" ]; then
|
||||
echo "HTML 报告已生成: $REPORT_DIR"
|
||||
else
|
||||
echo "未检测到HTML报告 "
|
||||
echo "可能是测试运行中途崩溃,或者未生成报告。"
|
||||
echo "请检查日志或目录: $REPORT_DIR"
|
||||
fi
|
||||
echo ""
|
||||
# 以 test-runner 的退出码退出
|
||||
exit $EXIT_CODE
|
||||
@@ -78,6 +78,7 @@ test('DevContainer 功能和配置', async ({ page,context }) => {
|
||||
//第二次刷新,容器应该正常启动了
|
||||
await page.reload({ waitUntil: 'domcontentloaded' });
|
||||
await expect(stopButton).toBeVisible({ timeout: 30000 });
|
||||
await page.screenshot({ path: 'full-page.png', fullPage: true });
|
||||
}
|
||||
console.log("Dev container 创建成功!");
|
||||
await page.getByRole('button',{ name: '停止开发容器'}).click();
|
||||
@@ -94,6 +95,10 @@ test('DevContainer 功能和配置', async ({ page,context }) => {
|
||||
await page.getByRole('link',{name: 'open with WebTerminal'}).click();
|
||||
const newPage = await pagePromise;
|
||||
await newPage.waitForLoadState(); // 等待新页面加载完成
|
||||
await page.reload({ waitUntil: 'domcontentloaded' });
|
||||
await page.waitForTimeout(30000);
|
||||
await page.reload({ waitUntil: 'domcontentloaded' });
|
||||
await page.screenshot({ path: 'full-page.png', fullPage: true });
|
||||
console.log("Web Terminal: 新标签页已打开!");
|
||||
//await expect(newPage.getByText('Successfully connected to the container')).toBeVisible(); //这里ttyd里的信息PlayWright看不见,容器的交互没办法自动化测试
|
||||
await page.getByRole('link', { name: '删除开发容器' }).click();
|
||||
|
||||
Reference in New Issue
Block a user