Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

!Don't merge yet! Add unit tests #12

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extension": ["ts"],
"spec": "src/**/*.spec.ts",
"require": "ts-node/register"
}
43 changes: 0 additions & 43 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,46 +31,3 @@ This project follows
## Adding commands

The BiDi commands are processed in the `src/bidiMapper/commandProcessor.ts`. To add a new command, add it to `_processCommand`, write and call processor for it.

## Debugging

If you use VS Code, you can create folder `.vscode`, and put 2 files in it:

1. `.vscode/launch.json`. Remember to provide the proper `BROWSER_PATH`.

```
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "pwa-node",
"request": "launch",
"name": "Run Server",
"skipFiles": ["<node_internals>/**"],
"cwd": "${workspaceFolder}",
"console": "externalTerminal",
"program": "${workspaceFolder}/src/.build/index.js",
"outFiles": ["${workspaceFolder}/src/.build/**/*.js"],
"env": {
"DEBUG": "*",
"PORT": "8080",
"BROWSER_PATH": "example/path/to/Chromium"
}
}
]
}
```

2. `.vscode/settings.json`

```
{
"python.testing.pytestArgs": ["tests"],
"python.testing.unittestEnabled": false,
"python.testing.nosetestsEnabled": false,
"python.testing.pytestEnabled": true
}
```
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,28 @@ You can alson run the Server by using script `./runBiDiServer.sh`. It will write

## Running the Tests

**Note**: Most of the tests currently fail, but this is how to run them.
### Unit tests

The tests are written using Python, in order to learn how to eventually do this
Running:

npm run unit

### e2e tests

**Note**: Most of the e2e tests currently fail, but this is how to run them.

The e2e tests are written using Python, in order to learn how to eventually do this
in web-platform-tests. Python 3.6+ and some dependencies are required:

python3 -m pip install --user -r tests/requirements.txt

Running:

python3 -m pytest --rootdir=tests
npm run e2e

This will run the tests against an already running server on port 8080. Use the `PORT` environment variable to connect to another port:
This will run the e2e tests against an already running server on port 8080. Use the `PORT` environment variable to connect to another port:

PORT=8081 python3 -m pytest --rootdir=tests
PORT=8081 npm run e2e

## How does it work?

Expand Down
18 changes: 12 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
"type": "module",
"main": "index.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"bidi-server": "npm run build && npm run server --",
"server": "node ./src/.build/index.js",
"unit": "mocha",
"e2e": "python3 -m pytest --rootdir=tests",
"bidi-server": "npm run build && npm run server-no-build --",
"server-no-build": "node ./src/.build/server/index.js",
"build": "npm run prettier && npm run clean && rollup --config src/bidiMapper/rollup.config.js && tsc -b src/tsconfig.json",
"clean": "rimraf ./src/.build",
"prettier": "npx prettier --write . "
Expand All @@ -23,14 +24,19 @@
"ws": "^7.4.5"
},
"devDependencies": {
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-typescript": "^8.2.1",
"@types/rollup": "^0.54.0",
"@types/websocket": "^1.0.2",
"@types/mocha": "^8.2.2",
"@types/ws": "^7.4.4",
"@rollup/plugin-typescript": "^8.2.1",
"@rollup/plugin-json": "^4.1.0",
"chai": "^4.3.4",
"mocha": "^9.0.1",
"devtools-protocol": "^0.0.900357",
"prettier": "2.3.0",
"rimraf": "^3.0.2",
"rollup": "^2.47.0",
"typescript": "^4.2.4"
"typescript": "^4.2.4",
"ts-mockito": "^2.6.1"
}
}
18 changes: 9 additions & 9 deletions src/bidiMapper/commandProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ import { BrowsingContextProcessor } from './domains/context/browsingContextProce
import { Context } from './domains/context/context';

export class CommandProcessor {
private _cdpServer: IServer;
private _cdpClient: IServer;
private _bidiServer: IServer;
private _selfTargetId: string;
private _contextProcessor: BrowsingContextProcessor;

static run(cdpServer: IServer, bidiServer: IServer, selfTargetId: string) {
static run(cdpClient: IServer, bidiServer: IServer, selfTargetId: string) {
const commandProcessor = new CommandProcessor(
cdpServer,
cdpClient,
bidiServer,
selfTargetId
);
Expand All @@ -34,18 +34,18 @@ export class CommandProcessor {
}

private constructor(
cdpServer: IServer,
cdpClient: IServer,
bidiServer: IServer,
selfTargetId: string
) {
this._bidiServer = bidiServer;
this._cdpServer = cdpServer;
this._cdpClient = cdpClient;
this._selfTargetId = selfTargetId;
}

private run() {
this._contextProcessor = new BrowsingContextProcessor(
this._cdpServer,
this._cdpClient,
this._selfTargetId,
(t: Context) => {
return this._onContextCreated(t);
Expand All @@ -55,7 +55,7 @@ export class CommandProcessor {
}
);

this._cdpServer.setOnMessage((messageObj) => {
this._cdpClient.setOnMessage((messageObj) => {
return this._onCdpMessage(messageObj);
});
this._bidiServer.setOnMessage((messageObj) => {
Expand Down Expand Up @@ -101,7 +101,7 @@ export class CommandProcessor {
});

private _process_browsingContext_getTree = async function (params) {
const cdpTargets = await this._cdpServer.sendMessage({
const cdpTargets = await this._cdpClient.sendMessage({
method: 'Target.getTargets',
});
const contexts = cdpTargets.targetInfos
Expand All @@ -112,7 +112,7 @@ export class CommandProcessor {
};

private async _process_DEBUG_Page_close(params) {
await this._cdpServer.sendMessage({
await this._cdpClient.sendMessage({
method: 'Target.closeTarget',
params: { targetId: params.context },
});
Expand Down
9 changes: 5 additions & 4 deletions src/bidiMapper/domains/context/browsingContextProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,27 @@
import { log } from '../../utils/log';
import { IServer } from '../../utils/iServer';
import { Context } from './context';
import { TargetInfo } from './targetInfo';
const logContext = log('context');

export class BrowsingContextProcessor {
private _contexts: Map<string, Context> = new Map();
private _sessionToTargets: Map<string, Context> = new Map();

// Set from outside.
private _cdpServer: IServer;
private _cdpClient: IServer;
private _selfTargetId: string;

private _onContextCreated: (t: Context) => Promise<void>;
private _onContextDestroyed: (t: Context) => Promise<void>;

constructor(
cdpServer: IServer,
cdpClient: IServer,
selfTargetId: string,
onContextCreated: (t: Context) => Promise<void>,
onContextDestroyed: (t: Context) => Promise<void>
) {
this._cdpServer = cdpServer;
this._cdpClient = cdpClient;
this._selfTargetId = selfTargetId;
this._onContextCreated = onContextCreated;
this._onContextDestroyed = onContextDestroyed;
Expand Down Expand Up @@ -102,7 +103,7 @@ export class BrowsingContextProcessor {
}

async process_createContext(params: any): Promise<any> {
const { targetId } = await this._cdpServer.sendMessage({
const { targetId } = await this._cdpClient.sendMessage({
method: 'Target.createTarget',
params: { url: params.url },
});
Expand Down
2 changes: 2 additions & 0 deletions src/bidiMapper/domains/context/context.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { TargetInfo } from './targetInfo';

export class Context {
_targetInfo: TargetInfo;
_contextId: string;
Expand Down
2 changes: 1 addition & 1 deletion src/bidiMapper/domains/context/targetInfo.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class TargetInfo {
export class TargetInfo {
targetId: string;
openerId: string | null;
url: string | null;
Expand Down
14 changes: 7 additions & 7 deletions src/bidiMapper/mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,23 +53,23 @@ const _waitSelfTargetIdPromise = _waitSelfTargetId();
window.document.documentElement.innerHTML = `<h1>Bidi mapper runs here!</h1><h2>Don't close.</h2>`;
window.document.title = 'BiDi Mapper';

const cdpServer = _createCdpServer();
const cdpClient = _createCdpClient();
const bidiServer = _createBidiServer();

// Needed to filter out info related to BiDi target.
const selfTargetId = await _waitSelfTargetIdPromise;

// Needed to get events about new targets.
await _prepareCdp(cdpServer);
await _prepareCdp(cdpClient);

CommandProcessor.run(cdpServer, bidiServer, selfTargetId);
CommandProcessor.run(cdpClient, bidiServer, selfTargetId);

logSystem('launched');

bidiServer.sendMessage('launched');
})();

function _createCdpServer() {
function _createCdpClient() {
const cdpBinding = new ServerBinding(
(message) => {
globalObj.cdp.send(message);
Expand Down Expand Up @@ -103,15 +103,15 @@ async function _waitSelfTargetId(): Promise<string> {
});
}

async function _prepareCdp(cdpServer) {
async function _prepareCdp(cdpClient) {
// Needed to get events about new targets.
await cdpServer.sendMessage({
await cdpClient.sendMessage({
method: 'Target.setDiscoverTargets',
params: { discover: true },
});

// Needed to automatically attach to new targets.
await cdpServer.sendMessage({
await cdpClient.sendMessage({
method: 'Target.setAutoAttach',
params: {
autoAttach: true,
Expand Down
22 changes: 22 additions & 0 deletions src/bidiMapper/utils/cdpServer.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { CdpClient } from './cdpClient';
import { ServerBinding } from './iServer';
import { mock, instance, verify } from 'ts-mockito';

describe('CdpClient tests.', async () => {
it('given CdpClient, when `sendMessage` is called, then cdpBindings should be called with proper values', async () => {
const someMessage = {
someAttribute: 'someValue',
};
const expectedMessageStr = JSON.stringify({
...someMessage,
id: 0,
});

const mockBinding = mock(ServerBinding);
const cdpClient = new CdpClient(instance(mockBinding));

cdpClient.sendMessage(someMessage);

verify(mockBinding.sendMessage(expectedMessageStr)).called();
});
});
18 changes: 10 additions & 8 deletions src/bidiMapper/utils/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,18 @@
*/
export function log(type: string): (...message: any[]) => void {
return (...messages: any[]) => {
const elementId = type + '_log';
// If run in browser, add debug message to the page.
if (typeof window !== 'undefined' && window?.document?.documentElement) {
console.log(type, ...messages);

if (!window.document.getElementById(elementId)) {
window.document.documentElement.innerHTML += `<h3>${type}:</h3><pre id='${elementId}'></pre>`;
window.document.getElementById(elementId);
}
const elementId = type + '_log';

const element = window.document.getElementById(elementId);
if (!window.document.getElementById(elementId)) {
window.document.documentElement.innerHTML += `<h3>${type}:</h3><pre id='${elementId}'></pre>`;
}

console.log.apply(null, [type].concat(messages));
element.innerText += messages.join(', ') + '\n';
const element = window.document.getElementById(elementId);
element.innerText += messages.join(', ') + '\n';
}
};
}