Skip to content

Commit d19d14a

Browse files
committed
Add end-to-end tests
1 parent cbf06aa commit d19d14a

File tree

29 files changed

+814
-157
lines changed

29 files changed

+814
-157
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: End-to-end tests CI
2+
on: [pull_request]
3+
jobs:
4+
test:
5+
runs-on: ubuntu-latest
6+
steps:
7+
- uses: actions/checkout@v2
8+
- name: Test using Node.js
9+
uses: actions/setup-node@v1
10+
with:
11+
node-version: "v20.11.0"
12+
- run: npm install
13+
- name: Build e2e outputs
14+
run: npm run dev:e2e
15+
- name: Build production outputs
16+
run: npm run build
17+
18+
- name: Run tests
19+
env:
20+
USE_HEADLESS_PUPPETEER: true
21+
run: npm run test-e2e
22+
- name: Tests ✅
23+
if: ${{ success() }}
24+
run: |
25+
curl --request POST --url https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }} --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' --header 'content-type: application/json' --data '{
26+
"context": "tests",
27+
"state": "success",
28+
"description": "Tests passed",
29+
"target_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
30+
}'
31+
- name: Tests 🚨
32+
if: ${{ failure() }}
33+
run: |
34+
curl --request POST --url https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }} --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' --header 'content-type: application/json' --data '{
35+
"context": "tests",
36+
"state": "failure",
37+
"description": "Tests failed",
38+
"target_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
39+
}

.github/workflows/tests.yml

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
name: Tests CI
2-
on: [push, pull_request]
2+
on: [ push, pull_request ]
33
jobs:
4-
test:
5-
runs-on: ubuntu-latest
6-
steps:
7-
- uses: actions/checkout@v2
8-
- name: Test using Node.js
9-
uses: actions/setup-node@v1
10-
with:
11-
node-version: "v20.11.0"
12-
- run: npm install
13-
- run: npm run test
14-
- name: Tests ✅
15-
if: ${{ success() }}
16-
run: |
17-
curl --request POST --url https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }} --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' --header 'content-type: application/json' --data '{
18-
"context": "tests",
19-
"state": "success",
20-
"description": "Tests passed",
21-
"target_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
22-
}'
23-
- name: Tests 🚨
24-
if: ${{ failure() }}
25-
run: |
26-
curl --request POST --url https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }} --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' --header 'content-type: application/json' --data '{
27-
"context": "tests",
28-
"state": "failure",
29-
"description": "Tests failed",
30-
"target_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
31-
}
4+
test:
5+
runs-on: ubuntu-latest
6+
steps:
7+
- uses: actions/checkout@v2
8+
- name: Test using Node.js
9+
uses: actions/setup-node@v1
10+
with:
11+
node-version: "v20.11.0"
12+
- run: npm install
13+
- run: npm run test
14+
- name: Tests ✅
15+
if: ${{ success() }}
16+
run: |
17+
curl --request POST --url https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }} --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' --header 'content-type: application/json' --data '{
18+
"context": "tests",
19+
"state": "success",
20+
"description": "Tests passed",
21+
"target_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
22+
}'
23+
- name: Tests 🚨
24+
if: ${{ failure() }}
25+
run: |
26+
curl --request POST --url https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }} --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' --header 'content-type: application/json' --data '{
27+
"context": "tests",
28+
"state": "failure",
29+
"description": "Tests failed",
30+
"target_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
31+
}

.vscode/settings.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"clbbddpinhgdejpoepalbfnkogbobfdb",
1919
"countup",
2020
"daterange",
21+
"domcontentloaded",
2122
"dont",
2223
"echarts",
2324
"emsp",
@@ -40,6 +41,7 @@
4041
"webcomponents",
4142
"webstore",
4243
"webtime",
44+
"wfhg",
4345
"zrender"
4446
],
4547
"cSpell.ignorePaths": [

README-zh.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262

6363
如果你知道如何开发浏览器扩展,并且熟悉该项目的技术栈 ( TypeScript + vue3 + ElementPlus ),也可以贡献代码
6464

65-
参见[开发指南](./doc/dev-guide.md)
65+
参见[开发指南](./doc/dev-guide-zh.md)
6666

6767
> 当然也欢迎新手同学使用该项目作为学习项目自己练手
6868

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ You can [submit one issue](https://github.com/sheepzh/timer/issues) to us if you
6262

6363
#### 2. Participate in development
6464

65-
If you know how to develop browser extensions and are familiar with the project's technology stack ( TypeScript + vue3 + ElementPlus ), you can commit your code lines.
65+
If you know how to develop browser extensions and are familiar with the project's technology stack (TypeScript + Vue3 + Element Plus + Echarts), you can also contribute code
66+
67+
See the [Development Guide](./doc/dev-guide.md)
6668

6769
#### 3. Perfect translation
6870

doc/dev-guide-zh.md

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# 开发指南
2+
3+
## 1. 相关技术和工具
4+
5+
使用到的技术栈有:
6+
7+
- [webpack](https://github.com/webpack/webpack) + [TypeScript](https://github.com/microsoft/TypeScript)
8+
- [Vue3 (Composition API + JSX)](<https://vuejs.org/api/#:~:text=defineCustomElement()-,Composition%20API,-setup()>)
9+
- [sass](https://github.com/sass/sass)
10+
- [Element Plus](https://element-plus.gitee.io/)
11+
- [Echarts](https://github.com/apache/echarts)
12+
13+
以及 [Chrome Extension 开发文档](https://developer.chrome.com/docs/webstore/),目前 manifest 的版本 Chrome 和 Edge 使用的使 v3, Firefox 使用的是 v2。请注意接口兼容。
14+
15+
还集成了一些免费的开源工具:
16+
17+
- 单元测试工具 [jest](https://jestjs.io/docs/getting-started)
18+
- 单元测试覆盖率 [Codecov](https://app.codecov.io/gh/sheepzh/timer)
19+
- 端到端集成测试 [puppeteer](https://developer.chrome.com/docs/extensions/how-to/test/puppeteer)
20+
- 代码质量检测 [CODEBEAT](https://codebeat.co/projects/github-com-sheepzh-timer-main)
21+
- 多语言翻译管理 [Crowdin](https://crowdin.com/project/timer-chrome-edge-firefox)
22+
23+
## 2. 开发步骤
24+
25+
1. fork 自己的仓库
26+
2. 安装依赖
27+
28+
```shell
29+
npm install
30+
```
31+
32+
3. 创建对应的需求分支
33+
4. code
34+
5. run 开发环境
35+
首先执行命令
36+
37+
```shell
38+
npm run dev
39+
# 在 Firefox 中测试
40+
npm run dev:firefox
41+
```
42+
43+
项目根目录下会输出两个文件夹,dist_dev 和 dist_dev_firefox
44+
45+
然后根据测试浏览器导入不同目标到浏览器中:
46+
47+
- Chrome 和 Edge 导入 dist_dev 文件夹
48+
- Firefox 导入 dist_dev_firefox 文件夹下的 manifest.json 文件
49+
50+
6. 运行单元测试
51+
52+
```shell
53+
npm run test
54+
```
55+
56+
7. 运行端到端的集成测试
57+
58+
首先需要编译两次:集成编译和生产编译
59+
60+
```shell
61+
npm run dev:e2e
62+
npm run build
63+
```
64+
65+
然后执行测试
66+
67+
```shell
68+
npm run test-e2e
69+
```
70+
71+
如果需要使用 headless 模式启动 puppeteer,可以设置以下环境变量
72+
73+
```bash
74+
export USE_HEADLESS_PUPPETEER=true
75+
```
76+
77+
7. 提交 PR
78+
79+
请 PR 到主仓库的 milestone 分支,一般是下一次发布的次版本号(x.x.0)。如果没有,请联系作者添加
80+
81+
## 3. 应用架构设计
82+
83+
> todo
84+
85+
## 4. 目录结构
86+
87+
```plain
88+
project
89+
90+
└───doc # 文档
91+
92+
└───public # 静态资源
93+
|
94+
└───src
95+
| | manifest.ts # Chrome 和 Edge 的声明文件
96+
| | manifest-firefox.ts # Firefox 的声明文件
97+
| |
98+
| └───api # HTTP API 以及扩展 API 的兼容处理
99+
| |
100+
| └───pages # 用户界面相关代码
101+
| | |
102+
| | └───app # 后台页
103+
| | |
104+
| | └───popup # 弹窗页
105+
| | | |
106+
| | | └───skeleton.ts # 弹窗页骨架屏,加速打开速度
107+
| | | |
108+
| | | └───index.ts # 弹窗页真实界面
109+
| | |
110+
| | └───side # 侧边栏
111+
| | |
112+
| | └───[其他目录] # 公共代码
113+
| |
114+
| └───background # 后台服务,负责协调数据交互,Service Worker
115+
| |
116+
| └───content-script # 注入到用户页面里的脚本
117+
| |
118+
| └───service # 服务层
119+
| |
120+
| └───database # 数据访问层
121+
| |
122+
| └───i18n # 多语言
123+
| |
124+
| └───util # 工具包
125+
| |
126+
| └───common # 公共功能
127+
|
128+
└───test # 单测
129+
| └───__mock__
130+
| |
131+
| └───storage.ts # mock chrome.storage
132+
|
133+
└───test-e2e # 端到端测试
134+
|
135+
└───types # 补充声明
136+
|
137+
└───webpack # webpack 打包配置
138+
139+
```
140+
141+
## 5. 代码格式
142+
143+
请使用 VSCode 自带的代码格式工具,请<u>**禁用 Prettier Eslint**</u> 等格式化工具
144+
145+
- 尽量使用单引号
146+
- 在符合语法正确情况下,尽量保持代码简洁
147+
- 行尾无分号
148+
- 换行符使用 LF (\n),Windows 下需要执行以下指令关闭警告
149+
150+
```
151+
git config core.autocrlf false
152+
```
153+
154+
## 6. 多语言处理
155+
156+
用户界面的文本除了特定的专业名词可以使用英语之外,其余请使用多语言框架注入文本。见代码目录 `src/i18n`
157+
158+
### 如何新增多语言条目
159+
160+
1. 在定义文件 `xxx.ts` 中新增一个字段。
161+
2. 然后在对应资源文件 `xxx-resource.json` 中 <u>新增该字段的英语 (en) 和简体中文 (zh_CN) 的对应文本</u> 即可。
162+
3. 在代码中调用 t(文本路径) 获取文本内容。
163+
164+
### 如何与 Crowdin 集成
165+
166+
Crowdin 是一个协作翻译平台,可以让 native 用户帮助翻译多语言内容。该项目与 Crowdin 的集成主要分为两步。
167+
168+
1. 上传英语文本和代码中的其他语种文本
169+
170+
```
171+
# 上传英语原始文本
172+
ts-node ./script/crowdin/sync-source.ts
173+
# 上传本地代码中其他语种的文本(不包括简体中文)
174+
ts-node ./script/crowdin/sync-translation.ts
175+
```
176+
177+
因为上述两个脚本,依赖在环境变量中的 Crowdin access secret。所以我将它们集成到了 Github 的 [Action](https://github.com/sheepzh/timer/actions/workflows/crowdin-sync.yml) 中。
178+
179+
2. 导出 Crowdin 中翻译完成的内容
180+
181+
```
182+
ts-node ./script/crowdin/export-translation.ts
183+
```
184+
185+
同样也可以直接执行 [Action](https://github.com/sheepzh/timer/actions/workflows/crowdin-export.yml)

0 commit comments

Comments
 (0)