Skip to content

Commit 7a1c3de

Browse files
committed
chore: convert extension to TypeScript and vitest
1 parent ddf3692 commit 7a1c3de

36 files changed

+912
-811
lines changed

.circleci/src/pipeline/@pipeline.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,7 @@ jobs:
17851785
source ./scripts/ensure-node.sh
17861786
yarn lerna run types
17871787
- sanitize-verify-and-store-mocha-results:
1788-
expectedResultCount: 7
1788+
expectedResultCount: 6
17891789

17901790
verify-release-readiness:
17911791
<<: *defaults

guides/esm-migration.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ When migrating some of these projects away from the `ts-node` entry [see `@packa
4848
- [x] packages/error ✅ **COMPLETED**
4949
- [x] packages/eslint-config ✅ **COMPLETED**
5050
- [ ] packages/example
51-
- [ ] packages/extension
51+
- [x] packages/extension**COMPLETED**
5252
- [ ] packages/frontend-shared **PARTIAL** - entry point is JS
5353
- [x] packages/electron ✅ **COMPLETED**
5454
- [x] packages/https-proxy - ✅ **COMPLETED**
@@ -99,7 +99,7 @@ When migrating some of these projects away from the `ts-node` entry [see `@packa
9999
- [x] packages/driver ✅ **COMPLETED**
100100
- [x] packages/electron ✅ **COMPLETED**
101101
- [x] packages/error ✅ **COMPLETED**
102-
- [ ] packages/extension
102+
- [x] packages/extension**COMPLETED**
103103
- [x] packages/https-proxy ✅ **COMPLETED**
104104
- [x] packages/electron ✅ **COMPLETED**
105105
- [x] packages/icons ✅ **COMPLETED**

packages/extension/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
app-dist/
2+
lib-dist/

packages/extension/app/v2/background.js renamed to packages/extension/app/v2/background.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
const get = require('lodash/get')
2-
const once = require('lodash/once')
3-
const Promise = require('bluebird')
4-
const browser = require('webextension-polyfill')
1+
import get from 'lodash/get'
2+
import once from 'lodash/once'
3+
import Bluebird from 'bluebird'
4+
import browser from 'webextension-polyfill'
55

6-
const client = require('./client')
6+
import { connect as clientConnect } from './client'
77

88
const checkIfFirefox = async () => {
99
if (!browser || !get(browser, 'runtime.getBrowserInfo')) {
@@ -15,17 +15,17 @@ const checkIfFirefox = async () => {
1515
return name === 'Firefox'
1616
}
1717

18-
const connect = function (host, path, extraOpts) {
18+
const connect = function (host: string, path: string, extraOpts?: any) {
1919
const listenToCookieChanges = once(() => {
20-
return browser.cookies.onChanged.addListener((info) => {
20+
return browser.cookies.onChanged.addListener((info: any) => {
2121
if (info.cause !== 'overwrite') {
2222
return ws.emit('automation:push:request', 'change:cookie', info)
2323
}
2424
})
2525
})
2626

2727
const listenToDownloads = once(() => {
28-
browser.downloads.onCreated.addListener((downloadItem) => {
28+
browser.downloads.onCreated.addListener((downloadItem: any) => {
2929
ws.emit('automation:push:request', 'create:download', {
3030
id: `${downloadItem.id}`,
3131
filePath: downloadItem.filename,
@@ -34,7 +34,7 @@ const connect = function (host, path, extraOpts) {
3434
})
3535
})
3636

37-
browser.downloads.onChanged.addListener((downloadDelta) => {
37+
browser.downloads.onChanged.addListener((downloadDelta: any) => {
3838
const state = (downloadDelta.state || {}).current
3939

4040
if (state === 'complete') {
@@ -51,29 +51,30 @@ const connect = function (host, path, extraOpts) {
5151
})
5252
})
5353

54-
const fail = (id, err) => {
54+
const fail = (id: number, err: any) => {
5555
return ws.emit('automation:response', id, {
5656
__error: err.message,
5757
__stack: err.stack,
5858
__name: err.name,
5959
})
6060
}
6161

62-
const invoke = function (method, id, ...args) {
63-
const respond = (data) => {
62+
const invoke = function (method: string, id: number, ...args: any[]) {
63+
const respond = (data: any) => {
6464
return ws.emit('automation:response', id, { response: data })
6565
}
6666

67-
return Promise.try(() => {
67+
return Bluebird.try(() => {
68+
// @ts-expect-error
6869
return automation[method].apply(automation, args.concat(respond))
6970
}).catch((err) => {
7071
return fail(id, err)
7172
})
7273
}
7374

74-
const ws = client.connect(host, path, extraOpts)
75+
const ws = clientConnect(host, path, extraOpts)
7576

76-
ws.on('automation:request', (id, msg, data) => {
77+
ws.on('automation:request', (id: number, msg: string, data: any) => {
7778
switch (msg) {
7879
case 'reset:browser:state':
7980
return invoke('resetBrowserState', id)
@@ -82,7 +83,7 @@ const connect = function (host, path, extraOpts) {
8283
}
8384
})
8485

85-
ws.on('automation:config', async (config) => {
86+
ws.on('automation:config', async (config: any) => {
8687
const isFirefox = await checkIfFirefox()
8788

8889
listenToCookieChanges()
@@ -99,15 +100,13 @@ const connect = function (host, path, extraOpts) {
99100
return ws
100101
}
101102

102-
const automation = {
103+
export const automation = {
103104
connect,
104105

105-
resetBrowserState (fn) {
106+
resetBrowserState (fn: any) {
106107
// We remove browser data. Firefox goes through this path, while chrome goes through cdp automation
107108
// Note that firefox does not support fileSystems or serverBoundCertificates
108109
// (https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browsingData/DataTypeSet).
109110
return browser.browsingData.remove({}, { cache: true, cookies: true, downloads: true, formData: true, history: true, indexedDB: true, localStorage: true, passwords: true, pluginData: true, serviceWorkers: true }).then(fn)
110111
},
111112
}
112-
113-
module.exports = automation

packages/extension/app/v2/client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { client } from '@packages/socket/browser/client'
22

3-
export const connect = (host, path, extraOpts = {}) => {
3+
export const connect = (host: string, path: string, extraOpts: any = {}) => {
44
return client(host, {
55
path,
66
transports: ['websocket'],
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
const background = require('./background')
1+
import { automation } from './background'
22

33
const HOST = 'CHANGE_ME_HOST'
44
const PATH = 'CHANGE_ME_PATH'
55

66
// immediately connect
7-
background.connect(HOST, PATH)
7+
automation.connect(HOST, PATH)

packages/extension/app/v3/content.js renamed to packages/extension/app/v3/content.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ window.addEventListener('message', ({ data, source }) => {
2626
})
2727

2828
// this listens for messages from the background service worker script
29-
port.onMessage.addListener(({ message }) => {
29+
port.onMessage.addListener(({ message }: { message: string }) => {
3030
// this lets us know the message we sent to the background script to activate
3131
// the main tab was successful, so we in turn send it on to Cypress
3232
// via postMessage

packages/extension/app/v3/service-worker.js renamed to packages/extension/app/v3/service-worker.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* global chrome */
1+
declare let chrome: any
22

33
// this background script runs in a service worker. it has access to the
44
// extension API, but not direct access the web page or anything else
@@ -9,10 +9,9 @@
99
// go to `chrome://extensions` and hit the reload button under the Cypress
1010
// extension. sometimes that doesn't work and requires re-launching Chrome
1111
// and then reloading the extension via `chrome://extensions`
12-
13-
async function getFromStorage (key) {
12+
async function getFromStorage (key: string) {
1413
return new Promise((resolve) => {
15-
chrome.storage.local.get(key, (storage) => {
14+
chrome.storage.local.get(key, (storage: any) => {
1615
resolve(storage[key])
1716
})
1817
})
@@ -23,7 +22,7 @@ async function activateMainTab () {
2322
const url = await getFromStorage('mostRecentUrl')
2423
const tabs = await chrome.tabs.query({})
2524

26-
const cypressTab = tabs.find((tab) => tab.url.includes(url))
25+
const cypressTab = tabs.find((tab: any) => tab.url.includes(url))
2726

2827
if (!cypressTab) return
2928

@@ -41,8 +40,8 @@ async function activateMainTab () {
4140

4241
// here we connect to the content script, which has access to the web page
4342
// running Cypress, but not the extension API
44-
chrome.runtime.onConnect.addListener((port) => {
45-
port.onMessage.addListener(async ({ message, url }) => {
43+
chrome.runtime.onConnect.addListener((port: any) => {
44+
port.onMessage.addListener(async ({ message, url }: { message: string, url: string }) => {
4645
if (message === 'activate:main:tab') {
4746
await activateMainTab()
4847

packages/extension/gulpfile.ts

Lines changed: 36 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,87 @@
1+
import { promisify } from 'util'
2+
import { exec } from 'child_process'
13
import gulp from 'gulp'
24
import { rimraf } from 'rimraf'
3-
import { waitUntilIconsBuilt } from '../../scripts/ensure-icons'
4-
import cp from 'child_process'
5-
import * as path from 'path'
5+
import { getPathToIcon, getPathToLogo } from '@packages/icons'
66

7-
const nodeWebpack = path.join(__dirname, '..', '..', 'scripts', 'run-webpack.js')
7+
const execAsync = promisify(exec)
88

9-
async function cypressIcons () {
10-
await waitUntilIconsBuilt()
9+
export async function clean (): Promise<boolean> {
10+
const removedAppDist = await rimraf('app-dist')
11+
const removedLibDist = await rimraf('lib-dist')
1112

12-
return require('@packages/icons')
13-
}
14-
15-
function clean (): Promise<boolean> {
16-
return rimraf('dist')
13+
return removedAppDist && removedLibDist
1714
}
1815

1916
const manifest = (v: 'v2' | 'v3') => {
2017
return () => {
2118
return gulp.src(`app/${v}/manifest.json`)
22-
.pipe(gulp.dest(`dist/${v}`))
19+
.pipe(gulp.dest(`app-dist/${v}`))
2320
}
2421
}
2522

26-
const background = (cb) => {
27-
cp.fork(nodeWebpack, { stdio: 'inherit' }).on('exit', (code) => {
28-
cb(code === 0 ? null : new Error(`Webpack process exited with code ${code}`))
29-
})
23+
const buildBackgroundV2 = async () => {
24+
await execAsync('yarn build:background')
3025
}
3126

32-
const copyScriptsForV3 = () => {
33-
return gulp.src('app/v3/*.js')
34-
.pipe(gulp.dest('dist/v3'))
27+
const buildApp = async () => {
28+
await execAsync('yarn build:app')
29+
}
30+
31+
const buildLib = async () => {
32+
await execAsync('yarn build:lib')
3533
}
3634

3735
const html = () => {
3836
return gulp.src('app/**/*.html')
39-
.pipe(gulp.dest('dist/v2'))
40-
.pipe(gulp.dest('dist/v3'))
37+
.pipe(gulp.dest('app-dist/v2'))
38+
.pipe(gulp.dest('app-dist/v3'))
4139
}
4240

4341
const css = () => {
4442
return gulp.src('app/**/*.css')
45-
.pipe(gulp.dest('dist/v2'))
46-
.pipe(gulp.dest('dist/v3'))
43+
.pipe(gulp.dest('app-dist/v2'))
44+
.pipe(gulp.dest('app-dist/v3'))
4745
}
4846

4947
const icons = async () => {
50-
const cyIcons = await cypressIcons()
51-
5248
return gulp.src([
53-
cyIcons.getPathToIcon('icon_16x16.png'),
54-
cyIcons.getPathToIcon('icon_19x19.png'),
55-
cyIcons.getPathToIcon('icon_38x38.png'),
56-
cyIcons.getPathToIcon('icon_48x48.png'),
57-
cyIcons.getPathToIcon('icon_128x128.png'),
49+
getPathToIcon('icon_16x16.png'),
50+
getPathToIcon('icon_19x19.png'),
51+
getPathToIcon('icon_38x38.png'),
52+
getPathToIcon('icon_48x48.png'),
53+
getPathToIcon('icon_128x128.png'),
5854
])
59-
.pipe(gulp.dest('dist/v2/icons'))
60-
.pipe(gulp.dest('dist/v3/icons'))
55+
.pipe(gulp.dest('app-dist/v2/icons'))
56+
.pipe(gulp.dest('app-dist/v3/icons'))
6157
}
6258

6359
const logos = async () => {
64-
const cyIcons = await cypressIcons()
65-
6660
// appease TS
6761
return gulp.src([
68-
cyIcons.getPathToLogo('cypress-bw.png'),
62+
getPathToLogo('cypress-bw.png'),
6963
])
70-
.pipe(gulp.dest('dist/v2/logos'))
71-
.pipe(gulp.dest('dist/v3/logos'))
64+
.pipe(gulp.dest('app-dist/v2/logos'))
65+
.pipe(gulp.dest('app-dist/v3/logos'))
7266
}
7367

74-
const build = gulp.series(
68+
export const build = gulp.series(
7569
clean,
70+
buildApp,
71+
buildBackgroundV2,
7672
gulp.parallel(
7773
icons,
7874
logos,
7975
manifest('v2'),
8076
manifest('v3'),
81-
background,
82-
copyScriptsForV3,
8377
html,
8478
css,
79+
buildLib,
8580
),
8681
)
8782

8883
const watchBuild = () => {
8984
return gulp.watch('app/**/*', build)
9085
}
9186

92-
const watch = gulp.series(build, watchBuild)
93-
94-
module.exports = {
95-
build,
96-
clean,
97-
watch,
98-
}
87+
export const watch = gulp.series(build, watchBuild)

packages/extension/index.d.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)