mirror of
https://github.com/morten-olsen/parcel.git
synced 2026-02-07 17:26:32 +01:00
feat: Add E2E tests (#4)
This commit is contained in:
20
.github/workflows/qa.yml
vendored
Normal file
20
.github/workflows/qa.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
name: QA
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout 🛎️
|
||||
uses: actions/checkout@v2.3.1 # If you're using actions/checkout@v2 you must set persist-credentials to false in most cases for the deployment to work correctly.
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install 🔧
|
||||
run: |
|
||||
yarn install
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
yarn test
|
||||
@@ -0,0 +1,17 @@
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Version: OpenPGP.js v4.10.7
|
||||
Comment: https://openpgpjs.org
|
||||
|
||||
wcDMAwd2QSi0rCknAQv/TOSkfzJeI4QeOGhTnPPH1Dbc0lXfJJFO/7k+hEaU
|
||||
nuj2ZETCJGBfTlktMdDq6pHcdXh1oLRW6mWxzBugspmJc1Hw7953+7oas0OF
|
||||
jf4k8Jwg87AQcea38t8pJYvfhKQe7qXR3aqnXCzb0PYzTloBsM+/S3j+qYsT
|
||||
TlDeN8LZfrGpBheGhiFI+XXIfbUSYNekIayj+u/HOiTNY4WCQKji44BC//oA
|
||||
IGKKyMLTBNjr86qYZF6Cowph4XMs9HhDP7OowPShdvArk2gvdELGD23Ywp1w
|
||||
2f6v6PUg8nSzleeETwnxLA3LKZZOz0/JYf30Q9gFr6uHf3tF510iO+KicjvS
|
||||
Y+OQ7k800ZFsLKdEy0bWySNUYyb9lycaOofR8Xm5GP0bs8/T6IoS4x6ii342
|
||||
dP/GcfRqLPbhM5LK9hbLpHRgpWyZsi+Or8Oyky6sPEvhFuecCPBb25Qju8ul
|
||||
VXfvIZqShw8pE1irbZlGQbFTq3yv8W2Ullu/QBwivDv1nL2bhocl0jsBFkSS
|
||||
qNqruW5Pim0exfz3HcnPvWxRxaolalGSRebb/MPcOz+ypw8wl3yuU+tLtNFK
|
||||
tfRdoo5leF334g==
|
||||
=gbKf
|
||||
-----END PGP MESSAGE-----
|
||||
7
jest.config.js
Normal file
7
jest.config.js
Normal file
@@ -0,0 +1,7 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
testEnvironment: path.join(__dirname, 'tests', 'env.js'),
|
||||
};
|
||||
13
package.json
13
package.json
@@ -4,7 +4,8 @@
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"build": "webpack"
|
||||
"build": "webpack",
|
||||
"test": "jest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ant-design/icons": "^4.2.2",
|
||||
@@ -13,7 +14,11 @@
|
||||
"@babel/preset-react": "^7.10.4",
|
||||
"@babel/preset-typescript": "^7.10.4",
|
||||
"@hot-loader/react-dom": "^16.13.0",
|
||||
"@types/express": "^4.17.11",
|
||||
"@types/fs-extra": "^9.0.7",
|
||||
"@types/get-port": "^4.2.0",
|
||||
"@types/html-webpack-plugin": "^3.2.3",
|
||||
"@types/jest": "^26.0.20",
|
||||
"@types/jszip": "^3.4.1",
|
||||
"@types/openpgp": "^4.4.12",
|
||||
"@types/react": "^16.9.46",
|
||||
@@ -29,11 +34,17 @@
|
||||
"babel-plugin-transform-inline-environment-variables": "^0.4.3",
|
||||
"css-loader": "^4.2.1",
|
||||
"dotenv": "^8.2.0",
|
||||
"express": "^4.17.1",
|
||||
"fs-extra": "^9.1.0",
|
||||
"get-port": "^5.1.1",
|
||||
"html-webpack-plugin": "^4.3.0",
|
||||
"jest": "^26.6.3",
|
||||
"offline-plugin": "^5.0.7",
|
||||
"parcel-bundler": "^1.12.4",
|
||||
"puppeteer": "^7.1.0",
|
||||
"react-hot-loader": "^4.12.21",
|
||||
"style-loader": "^1.2.1",
|
||||
"ts-jest": "^26.5.1",
|
||||
"ts-node": "^8.10.2",
|
||||
"typescript": "^3.9.7",
|
||||
"webpack": "^4.44.1",
|
||||
|
||||
@@ -67,6 +67,7 @@ const FileView: React.FC<Props> = ({
|
||||
actions.push(
|
||||
<IconText
|
||||
icon={DownloadOutlined}
|
||||
className="msg-download"
|
||||
type="primary"
|
||||
text="Download"
|
||||
onClick={() => downloadLink(file.name, file.blob!)}
|
||||
@@ -77,6 +78,7 @@ const FileView: React.FC<Props> = ({
|
||||
return (
|
||||
<List.Item
|
||||
actions={actions}
|
||||
className="msg-item"
|
||||
>
|
||||
<List.Item.Meta
|
||||
avatar={icon}
|
||||
|
||||
@@ -13,8 +13,8 @@ const Add: React.FC = () => {
|
||||
<>
|
||||
<Divider>
|
||||
<Radio.Group onChange={evt => setType(evt.target.value)} defaultValue={DEFAULT_VALUE}>
|
||||
<Radio.Button value="text"><FileTextOutlined /> Text</Radio.Button>
|
||||
<Radio.Button value="file"><FileOutlined /> File</Radio.Button>
|
||||
<Radio.Button className="add-text-tab" value="text"><FileTextOutlined /> Text</Radio.Button>
|
||||
<Radio.Button className="add-file-tab" value="file"><FileOutlined /> File</Radio.Button>
|
||||
</Radio.Group>
|
||||
</Divider>
|
||||
{type === 'text' && <AddText />}
|
||||
|
||||
@@ -19,12 +19,14 @@ const AddText : React.FC = () => {
|
||||
<Form.Item>
|
||||
<Input
|
||||
placeholder="Title"
|
||||
className="msg-title"
|
||||
value={name}
|
||||
onChange={evt => setName(evt.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Input.TextArea
|
||||
className="msg-body"
|
||||
placeholder="Your message here..."
|
||||
value={text}
|
||||
rows={6}
|
||||
@@ -34,6 +36,7 @@ const AddText : React.FC = () => {
|
||||
<Form.Item>
|
||||
<Button
|
||||
onClick={add}
|
||||
className="msg-add"
|
||||
type="primary"
|
||||
icon={<PlusOutlined />}
|
||||
disabled={!text}
|
||||
|
||||
1
src/global.d.ts
vendored
Normal file
1
src/global.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
declare var testUrl: string;
|
||||
@@ -16,6 +16,7 @@ const Thumb: React.FC = ({
|
||||
title,
|
||||
Icon,
|
||||
link,
|
||||
className,
|
||||
}) => {
|
||||
const history = useHistory();
|
||||
return (
|
||||
@@ -23,6 +24,7 @@ const Thumb: React.FC = ({
|
||||
size="large"
|
||||
icon={<Icon />}
|
||||
type="link"
|
||||
className={className}
|
||||
onClick={() => history.push(link)}
|
||||
>
|
||||
{title}
|
||||
@@ -39,15 +41,18 @@ const Intro = () => {
|
||||
<Thumb
|
||||
title="I want to send a text/file"
|
||||
link="/send"
|
||||
className="send-btn"
|
||||
Icon={UploadOutlined}
|
||||
/>
|
||||
<Thumb
|
||||
link="/key"
|
||||
className="want-to-receive-btn"
|
||||
title="I want to receive a file"
|
||||
Icon={KeyOutlined}
|
||||
/>
|
||||
<Thumb
|
||||
link="/receive"
|
||||
className="did-receive-btn"
|
||||
title="I have received a file"
|
||||
Icon={DownloadOutlined}
|
||||
/>
|
||||
|
||||
81
test-assets/key
Normal file
81
test-assets/key
Normal file
@@ -0,0 +1,81 @@
|
||||
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
|
||||
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
|
||||
9R+pJKNnVhsIEwEn
|
||||
=elvE
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
40
test-assets/key.pub
Normal file
40
test-assets/key.pub
Normal file
@@ -0,0 +1,40 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
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
|
||||
=dEQO
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
76
tests/encryption.test.ts
Normal file
76
tests/encryption.test.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import puppeteer, { Browser, Page } from 'puppeteer';
|
||||
import path from 'path';
|
||||
import fs from 'fs-extra';
|
||||
import { nanoid } from 'nanoid';
|
||||
import openpgp, { key, message } from 'openpgp';
|
||||
|
||||
const sleep = (time: number) => new Promise((resolve) => setTimeout(resolve, time));
|
||||
|
||||
describe('encryption', () => {
|
||||
let browser: Browser;
|
||||
let page: Page;
|
||||
let tmpDir: string;
|
||||
let keys: key.KeyResult;
|
||||
|
||||
const getText = async (elm: any) => {
|
||||
const text = await page.evaluate(el => el.textContent, elm);
|
||||
return text;
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
tmpDir = path.resolve(`.tmp/${nanoid}`);
|
||||
await fs.mkdirp(tmpDir);
|
||||
const data = await fs.readFile(
|
||||
path.join(__dirname, '..', 'test-assets', 'key'),
|
||||
'utf-8',
|
||||
);
|
||||
keys = await key.readArmored(data);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
browser = await puppeteer.launch({
|
||||
args: [
|
||||
'--no-sandbox',
|
||||
'--disable-setuid-sandbox',
|
||||
]
|
||||
});
|
||||
page = await browser.newPage();
|
||||
(page as any)._client.send('Page.setDownloadBehavior', {
|
||||
behavior: 'allow',
|
||||
downloadPath: tmpDir,
|
||||
});
|
||||
await page.goto(testUrl, {
|
||||
waitUntil: 'networkidle2',
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should be able to encrypt a text', async () => {
|
||||
await page.click('.send-btn');
|
||||
await page.click('.add-text-tab');
|
||||
await page.type('.msg-title', 'Foo');
|
||||
await page.type('.msg-body', 'Bar');
|
||||
await page.click('.msg-add');
|
||||
await sleep(300);
|
||||
const items = await page.$$('.msg-item');
|
||||
expect(items.length).toBe(1);
|
||||
const [item] = items;
|
||||
const title = await item.$('.ant-list-item-meta-title');
|
||||
const titleText = await getText(title);
|
||||
expect(titleText).toBe('Foo.txt.asc');
|
||||
await page.click('.msg-download');
|
||||
await sleep(300);
|
||||
const downloadPath = path.join(tmpDir, 'Foo.txt.asc');
|
||||
expect(fs.existsSync(downloadPath)).toBe(true);
|
||||
const data = await fs.readFile(downloadPath, 'utf-8');
|
||||
|
||||
const decrypted = await openpgp.decrypt({
|
||||
message: await message.readArmored(data),
|
||||
privateKeys: keys.keys[0],
|
||||
});
|
||||
expect(decrypted.data).toBe('Bar');
|
||||
});
|
||||
});
|
||||
50
tests/env-ts.ts
Normal file
50
tests/env-ts.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import NodeEnvironment from 'jest-environment-node';
|
||||
import { Server, createServer } from 'http';
|
||||
import getPort from 'get-port';
|
||||
import webpack from 'webpack';
|
||||
import path from 'path';
|
||||
import express from 'express';
|
||||
import createConfig from '../webpack.config';
|
||||
|
||||
const build = () => new Promise<Server>(async (resolve, reject) => {
|
||||
const config = await createConfig({
|
||||
test: true,
|
||||
});
|
||||
const port = await getPort();
|
||||
const bundler = webpack(config);
|
||||
bundler.run((err, stats) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
} else if (stats.hasErrors()) {
|
||||
return reject(new Error('Webpack errors'));
|
||||
}
|
||||
const app = express();
|
||||
app.use(express.static(path.join(__dirname, '..', 'dist')));
|
||||
const server = createServer(app);
|
||||
const listener = server.listen(port, '127.0.0.1', () => {
|
||||
resolve(listener);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
class CustomEnvironment extends NodeEnvironment {
|
||||
private _server?: Server;
|
||||
|
||||
constructor(config: any) {
|
||||
super(config);
|
||||
}
|
||||
|
||||
async setup() {
|
||||
await super.setup();
|
||||
this._server = await build();
|
||||
const address: any = this._server?.address();
|
||||
this.global.testUrl = `http://${address.address}:${address.port}`
|
||||
}
|
||||
|
||||
async teardown() {
|
||||
await super.teardown();
|
||||
this._server?.close();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CustomEnvironment;
|
||||
4
tests/env.js
Normal file
4
tests/env.js
Normal file
@@ -0,0 +1,4 @@
|
||||
require('ts-node/register');
|
||||
const Env = require('./env-ts');
|
||||
|
||||
module.exports = Env;
|
||||
@@ -1,10 +1,15 @@
|
||||
require('dotenv').config();
|
||||
import webpack, { Configuration } from 'webpack';
|
||||
import axios from 'axios';
|
||||
import fs from 'fs';
|
||||
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
||||
import WorkboxWebpackPlugin from 'workbox-webpack-plugin';
|
||||
import path from 'path';
|
||||
|
||||
interface Options {
|
||||
test: boolean;
|
||||
}
|
||||
|
||||
const repo = process.env.GITHUB_REPOSITORY;
|
||||
if (!repo) {
|
||||
throw new Error('No GITHUB_REPOSITRY env variable found');
|
||||
@@ -13,7 +18,7 @@ const [username] = repo.split('/');
|
||||
|
||||
const __DEV__ = process.env.NODE_ENV !== 'production';
|
||||
|
||||
const createConfig = async ():Promise<Configuration> => {
|
||||
const getData = async () => {
|
||||
const { data: keyList } = await axios.get(`https://api.github.com/users/${username}/gpg_keys`);
|
||||
if (keyList.length === 0) {
|
||||
throw new Error(`The user ${username} does not have any GPG keys`);
|
||||
@@ -22,6 +27,24 @@ const createConfig = async ():Promise<Configuration> => {
|
||||
username,
|
||||
keys: keyList.map((key: any) => key.raw_key),
|
||||
};
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
const getTestData: typeof getData = async () => {
|
||||
const pubKey = fs.readFileSync(path.join(__dirname, 'test-assets', 'key.pub'), 'utf-8');
|
||||
return {
|
||||
username: 'foobar',
|
||||
keys: [
|
||||
pubKey,
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
const createConfig = async (options: Options = {
|
||||
test: false,
|
||||
}):Promise<Configuration> => {
|
||||
const data = await (options.test ? getTestData() : getData());
|
||||
const config: Configuration = {
|
||||
mode: __DEV__ ? 'development' : 'production',
|
||||
entry: {
|
||||
|
||||
Reference in New Issue
Block a user