Skip to content

Commit

Permalink
Merge pull request #247 from Anthony-YY/support_download_inspect
Browse files Browse the repository at this point in the history
support chrome download activity access under headless mode
  • Loading branch information
ArtMathArt authored Sep 25, 2024
2 parents b2f535a + 4db4169 commit 7544ca8
Show file tree
Hide file tree
Showing 17 changed files with 274 additions and 8 deletions.
3 changes: 3 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ ringcentralPreset.extends = ringcentralPreset.extends.map((item) => {

module.exports = {
...ringcentralPreset,
globals: {
chrome: 'writable',
},
env: {
...ringcentralPreset.env,
es6: true,
Expand Down
7 changes: 7 additions & 0 deletions packages/download-collector-crx/.mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"require" : "../../utils/ts-mocha.js",
"watch-extensions": "ts",
"timeout": 30000,
"reporter": "dot",
"spec": "test/**/*.spec.ts"
}
4 changes: 4 additions & 0 deletions packages/download-collector-crx/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
test
mocha.opts
tsconfig.json
4 changes: 4 additions & 0 deletions packages/download-collector-crx/.npmignore copy
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
test
mocha.opts
tsconfig.json
2 changes: 2 additions & 0 deletions packages/download-collector-crx/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
save-exact=true

29 changes: 29 additions & 0 deletions packages/download-collector-crx/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# @testring/dwnld-collector-crx

## Installation

```bash
npm install @testring/dwnld-collector-crx
```

## How to use
accessing chrome internal page like chrome://downloads is not allowed in headless mode, as a result, checking download results becomes unavaiable.
once this chrome extension installed. chrome download items can be accessed within page via localStorage, like this:
```javascript
const downloadsJSONStr = await browser.execute(() => {
return localStorage.getItem('_DOWNLOADS_');
})
// the result is already sort ASC by startTime
const downloads = JSON.parse(downloadsJSONStr);

```
downloads is an array of download items, each item has following properties:
```javascript
{
fileName: 'example.pdf',
filePath: '/Users/username/Downloads/example.pdf',
state: 'complete',
startTime: '2021-01-01T00:00:00.000Z',
state: 'complete',
}
```
3 changes: 3 additions & 0 deletions packages/download-collector-crx/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare module '@testring/dwnld-collector-crx' {
export const getCrxBase64: () => string;
}
18 changes: 18 additions & 0 deletions packages/download-collector-crx/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "@testring/dwnld-collector-crx",
"version": "0.6.11",
"main": "./dist/index.js",
"types": "./index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/ringcentral/testring.git"
},
"author": "RingCentral",
"license": "MIT",
"scripts": {
"postinstall": "mkdir -p dist && crx pack src/extension -o dist/extension.crx"
},
"dependencies": {
"crx": "5.0.1"
}
}
32 changes: 32 additions & 0 deletions packages/download-collector-crx/src/extension/background.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
chrome.downloads.onCreated.addListener((downloadItem) => {
chrome.tabs.query({}, (tabs) => {
tabs.forEach((tab) => {
chrome.tabs.sendMessage(tab.id, {
action: 'downloadStarted',
downloadItem,
});
});
});
});

chrome.downloads.onDeterminingFilename.addListener((downloadItem) => {
chrome.tabs.query({}, (tabs) => {
tabs.forEach((tab) => {
chrome.tabs.sendMessage(tab.id, {
action: 'downloadDetermined',
downloadItem,
});
});
});
});

chrome.downloads.onChanged.addListener((downloadItem) => {
chrome.tabs.query({}, (tabs) => {
tabs.forEach((tab) => {
chrome.tabs.sendMessage(tab.id, {
action: 'downloadChanged',
downloadItem,
});
});
});
});
48 changes: 48 additions & 0 deletions packages/download-collector-crx/src/extension/content.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const DOWNLOAD_KEY = "_DOWNLOADS_";
const DOWNLOADS_PERSISTED = localStorage.getItem(DOWNLOAD_KEY) ? JSON.parse(localStorage.getItem(DOWNLOAD_KEY) ?? "[]") : [];
const DOWNLOADS = DOWNLOADS_PERSISTED.reduce((acc, download) => {
acc[download.id] = download;
return acc;
}, {});

chrome.runtime.onMessage.addListener((message) => {
const {action, downloadItem} = message;
if (action === 'downloadStarted') {
DOWNLOADS[downloadItem.id] = {
id: downloadItem.id,
fileName: '',
fileUrl: '',
state: downloadItem.state,
startTime: new Date(downloadItem.startTime).getTime(),
};
updatePageVariable();
return;
}

if (action === 'downloadDetermined') {
const download = DOWNLOADS[downloadItem.id];
download.fileName = downloadItem.filename;
download.state = downloadItem.state;
updatePageVariable();
return;
}

if (action === 'downloadChanged') {
const download = DOWNLOADS[downloadItem.id];
const filePath = downloadItem.filename?.current;
const state = downloadItem.state?.current;
if (filePath) {
download.filePath = filePath;
}
if (state) {
download.state = state;
}
updatePageVariable();
}
});

function updatePageVariable() {
const downloads = Object.values(DOWNLOADS);
downloads.sort((a, b) => b.startTime - a.startTime);
localStorage.setItem('_DOWNLOADS_', JSON.stringify(downloads));
}
21 changes: 21 additions & 0 deletions packages/download-collector-crx/src/extension/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"manifest_version": 3,
"name": "Download Monitor Extension",
"version": "1.0",
"permissions": [
"downloads",
"downloads.shelf",
"tabs",
"activeTab",
"storage"
],
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
]
}
21 changes: 21 additions & 0 deletions packages/download-collector-crx/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const fs = require('fs');
const path = require('path');

const crxFilePath = path.join(__dirname, './extension.crx');

let CACHED_CRX_BASE64 = null;

function getCrxBase64() {
if (CACHED_CRX_BASE64) {
return CACHED_CRX_BASE64;
}

const crxData = fs.readFileSync(crxFilePath);
CACHED_CRX_BASE64 = crxData.toString('base64');

return CACHED_CRX_BASE64;
}

module.exports = {
getCrxBase64,
};
28 changes: 28 additions & 0 deletions packages/download-collector-crx/src/key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDBhPtoAnu/e1jg
OTn1twETyvuuri4i82iFL+Pxm5xFxb2f9y1apFgtPCV4ZQnReso4f60tojmWrk1b
3vZaXK3em9GgMaYOm76f+t6qY+w0IaGhg/NTj69pZ43pzxTkTXmc0CDqrz+0osWb
bh3qZdugcnxDmX3RSYQBMf/oWAjtkETbCnWaxX0m0WQGrXRbjVC+yQVEl7xNSFMW
PCS5T254Tv41i+q4LaL14D+PA1TXcwHTmfZyrX/Iz+deKZnlAK4kKFl9X+7c+y++
pnUYpwfhfkXwONwO/hy6c3c8f3PR/vegMsCuPCCzBHZrTXPdlFnKin6CAvzjB1r6
rznBVGOBAgMBAAECggEBAJnEvCvSRVhKf71zW222Y6HBmakceEaHWRbzjdFOj6cV
T+7K7nvmuLYA49k9l8afJg4szYPEMrRbfdaxXNlCaVnIQJJkwQk8kgT2x3Vm/qoR
yyfW/EL6mixL/4S4amZadXa4Hl+8rwcui4xMvHKjSxe7wKfKUCI7oyt7+lc5lKaG
p01BBYTHQaFUmuLRMxWlTZr6qZM1btXXd0A9qQQOUsRZ8N017LdB6+VYCWY1t36q
Ey8FrbZKVXFvwt9yd8MxdaOHmSpsIGLlnNpJykneP9f17tT8UskH0GQgjgZ9ba3I
8l1RysCP802pHOwaMfNtMYJ11i85tBaIz7AB/neZqJECgYEA+cLj7C2wYDvCiTd3
Nmp51sdM8UP4pYLF8F73XUNEyG6VRBXmzJqIOSKrlGqgEgfU/gjpWtdtef2NKMNY
fdz0k5Oyv7De+es24KI+7rlhP6Ptv7YM2urpm8C42i4iC7XBGtgxyaqnqPaQm283
TM4Tqdx40Y9TpMM2JYWuqd4aVV0CgYEAxlpza0b/2q6mM79T8eCdjjCRW1G8NMl8
PXvQrpPo0pLRrTptpqMDg7JRcCnxNifHGna8PsrzHkWVjsfwYkwbp2NANG+eoXI9
wTnqtIUsFTRCeqkKl3SPyi4EAih3bluEZC+WdvDiy3eWXiCfHxz/EVZGw9suoeCu
g/7oMjNi4HUCgYAkiyx4IRM+cV/8Xb42mwuqrkyGvJBD/0dg7TQ6VB5bSTrT1HSJ
mU63NWhvdc5n9PdoF/u0y/J7t+qQfUyUVeD/OswbmhB19sF3yqV0nnEpM54Uv9lP
qrF1lZQ2cCuRFQ3lFJ7sR+jyIulzpKkttrVP1C9lUhhF8j4Y7V9qAVJPDQKBgEg3
pHA5kGvZTK/oiDK3egXMDxA1iRWbCj4Ed20ocws/41FzxXp3PY9UfCwfSTBTeT1c
X5tpHu01noc2qoHPff4Kt9Sfkxzq0Csq4BZLqkoqFc48/5s3GCcfa9wxSZKHhYNI
hDrX52r3Jmss62JTl1aDmA41HhxYBpIOXBHy/ZwFAoGAEJnzQ1NzHH52MArcwrm5
Ku636x3PflPxP7aAYU3GbGJCLLsvS2V0ABxjk/VcHrHCbeIZxZ0YQX7BIAXOkO1a
Dh2fubgnpqDNFIyeFt9ZHJ0Zg5KC3NXK75ErbVSC3WPht3T3va7hITvGVbMkXCRA
Bducv2SfztUPms8SlB4GVIQ=
-----END PRIVATE KEY-----
Empty file.
22 changes: 22 additions & 0 deletions packages/download-collector-crx/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"compilerOptions": {
"target": "es2015",
"module": "commonjs",
"allowJs": false,
"moduleResolution": "node",
"noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true,
"preserveConstEnums": true,
"noEmitOnError": true,
"declaration": false,
"outDir": "dist",
"sourceMap": false,
"lib": ["es5", "es2015", "es2016", "es2017", "dom"],
"typeRoots": ["./node_modules/@types", "../../node_modules/@types"],
"noUnusedLocals": true,
"strictNullChecks": true,
"removeComments": false
},
"include": ["*.ts", "src/**/*.ts", "src/**/*.json"],
"exclude": ["./node_modules", "../../node_modules"]
}
1 change: 1 addition & 0 deletions packages/plugin-selenium-driver/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@nullcc/code-coverage-client": "1.4.2",
"@testring/child-process": "0.6.11",
"@testring/devtool-extension": "0.6.11",
"@testring/dwnld-collector-crx": "0.6.11",
"@testring/logger": "0.6.11",
"@testring/plugin-api": "0.6.11",
"@testring/types": "0.6.11",
Expand Down
39 changes: 31 additions & 8 deletions packages/plugin-selenium-driver/src/plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as deepmerge from 'deepmerge';

import {spawn} from '@testring/child-process';
import {loggerClient} from '@testring/logger';
import {getCrxBase64} from '@testring/dwnld-collector-crx';
import {absoluteExtensionPath} from '@testring/devtool-extension';
import {CDPCoverageCollector} from '@nullcc/code-coverage-client';

Expand Down Expand Up @@ -49,7 +50,7 @@ const DEFAULT_CONFIG: SeleniumPluginConfig = {
args: [] as string[],
},
},
cdpCoverage: false
cdpCoverage: false,
};

function delay(timeout) {
Expand Down Expand Up @@ -185,6 +186,23 @@ export class SeleniumPlugin implements IBrowserProxyPlugin {
mergedConfig.hostname = mergedConfig.host;
}

const googleChromeOptions = mergedConfig.capabilities?.['goog:chromeOptions'];
if (
googleChromeOptions &&
(
googleChromeOptions.args?.includes('--headless') ||
googleChromeOptions.args?.includes('headless')
)
) {
const extensions = mergedConfig.capabilities?.['goog:chromeOptions'].extensions;
const dowldMonitorCrx = getCrxBase64();
if (extensions) {
extensions.push(dowldMonitorCrx);
} else {
googleChromeOptions.extensions = [dowldMonitorCrx];
}
}

return mergedConfig;
}

Expand Down Expand Up @@ -331,7 +349,10 @@ export class SeleniumPlugin implements IBrowserProxyPlugin {
}
}

private async createClient(applicant: string, config?: Partial<WebdriverIO.Config>): Promise<void> {
private async createClient(
applicant: string,
config?: Partial<WebdriverIO.Config>,
): Promise<void> {
await this.waitForReadyState;
const clientData = this.browserClients.get(applicant);

Expand All @@ -350,7 +371,11 @@ export class SeleniumPlugin implements IBrowserProxyPlugin {
);
}

const _config: any = deepmerge.all([{}, this.config, config as any || {}]);
const _config: any = deepmerge.all([
{},
this.config,
(config as any) || {},
]);
const client = await remote(_config);

let sessionId: string;
Expand Down Expand Up @@ -424,10 +449,8 @@ export class SeleniumPlugin implements IBrowserProxyPlugin {
client.addCommand(
'deleteSessionId',
function (sessionId) {
const {
w3cCaps,
jsonwpCaps,
} = this.options.requestedCapabilities;
const {w3cCaps, jsonwpCaps} =
this.options.requestedCapabilities;

const sessionDeleteRequest = new WebDriverRequest(
'DELETE',
Expand Down Expand Up @@ -1189,7 +1212,7 @@ export class SeleniumPlugin implements IBrowserProxyPlugin {
},
},
},
} as any)
} as any);
}
}

Expand Down

0 comments on commit 7544ca8

Please sign in to comment.