Skip to content

Commit ae952b4

Browse files
committed
alert and confirm polyfills
1 parent 8e9e375 commit ae952b4

File tree

22 files changed

+535
-185
lines changed

22 files changed

+535
-185
lines changed

packages/selenium-ide/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,9 @@
112112
"@seleniumhq/code-export-ruby-rspec": "^4.0.0-alpha.3",
113113
"@seleniumhq/get-driver": "^4.0.0-alpha.3",
114114
"@seleniumhq/side-api": "^4.0.0-alpha.41",
115+
"@seleniumhq/side-commons": "^4.0.0-alpha.2",
115116
"@seleniumhq/side-model": "^4.0.0-alpha.5",
116-
"@seleniumhq/side-runtime": "^4.0.0-alpha.34",
117+
"@seleniumhq/side-runtime": "^4.0.0-alpha.35",
117118
"dnd-core": "^16.0.1",
118119
"electron-chromedriver": "^28.0.0",
119120
"electron-log": "^5.0.1",
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { WindowConfig } from 'browser/types'
2+
3+
const DEFAULT_WIDTH = 600
4+
const DEFAULT_HEIGHT = 600
5+
6+
export const window: WindowConfig['window'] = () => ({
7+
width: DEFAULT_WIDTH,
8+
height: DEFAULT_HEIGHT,
9+
minWidth: DEFAULT_WIDTH,
10+
minHeight: DEFAULT_HEIGHT,
11+
resizable: false,
12+
minimizable: false,
13+
fullscreenable: false,
14+
autoHideMenuBar: true,
15+
maximizable: false,
16+
show: false,
17+
skipTaskbar: true,
18+
alwaysOnTop: false,
19+
useContentSize: false,
20+
modal: true,
21+
title: 'Window Prompt Polyfill',
22+
webPreferences: {
23+
contextIsolation: true,
24+
nodeIntegration: false,
25+
sandbox: true,
26+
},
27+
})
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { contextBridge, ipcRenderer } from "electron"
2+
3+
function alertError(error: Error | string) {
4+
if (error instanceof Error) {
5+
error = error.message
6+
}
7+
8+
ipcRenderer.send('alert-error', error)
9+
}
10+
11+
function acceptAlert() {
12+
ipcRenderer.send('accept-alert')
13+
}
14+
15+
contextBridge.exposeInMainWorld('acceptAlert', acceptAlert);
16+
contextBridge.exposeInMainWorld('alertError', alertError);
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import Button from '@mui/material/Button'
2+
import Grid from '@mui/material/Grid'
3+
import Typography from '@mui/material/Typography'
4+
import AppWrapper from 'browser/components/AppWrapper'
5+
import renderWhenReady from 'browser/helpers/renderWhenReady'
6+
import React from 'react'
7+
8+
const Prompt = () => {
9+
// @ts-expect-error this exists
10+
const acceptAlert = () => window.acceptAlert(answerRef.current!.value);
11+
12+
React.useEffect(() => {
13+
window.addEventListener('error', (e) => {
14+
// @ts-expect-error this exists
15+
window.alertError(e.message)
16+
})
17+
}, [])
18+
19+
return (
20+
<AppWrapper>
21+
<Grid className="centered pt-4" container spacing={1}>
22+
<Grid item xs={12}>
23+
<Typography id="alert" variant="subtitle1" />
24+
</Grid>
25+
</Grid>
26+
<Grid className="centered" container spacing={1}>
27+
<Grid item xs={12}>
28+
<Button onClick={acceptAlert} variant="contained">
29+
OK
30+
</Button>
31+
</Grid>
32+
</Grid>
33+
</AppWrapper>
34+
)
35+
}
36+
37+
renderWhenReady(Prompt)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { WindowConfig } from 'browser/types'
2+
3+
const DEFAULT_WIDTH = 600
4+
const DEFAULT_HEIGHT = 600
5+
6+
export const window: WindowConfig['window'] = () => ({
7+
width: DEFAULT_WIDTH,
8+
height: DEFAULT_HEIGHT,
9+
minWidth: DEFAULT_WIDTH,
10+
minHeight: DEFAULT_HEIGHT,
11+
resizable: false,
12+
minimizable: false,
13+
fullscreenable: false,
14+
autoHideMenuBar: true,
15+
maximizable: false,
16+
show: false,
17+
skipTaskbar: true,
18+
alwaysOnTop: false,
19+
useContentSize: false,
20+
modal: true,
21+
title: 'Window Prompt Polyfill',
22+
webPreferences: {
23+
contextIsolation: true,
24+
nodeIntegration: false,
25+
sandbox: true,
26+
},
27+
})
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { contextBridge, ipcRenderer } from "electron"
2+
3+
function acceptConfirmation() {
4+
ipcRenderer.send('accept-confirmation', true)
5+
}
6+
7+
function confirmationError(error: Error | string) {
8+
if (error instanceof Error) {
9+
error = error.message
10+
}
11+
12+
ipcRenderer.send('confirmation-error', error)
13+
}
14+
15+
function dismissConfirmation() {
16+
ipcRenderer.send('dismiss-confirmation', false)
17+
}
18+
19+
contextBridge.exposeInMainWorld('dismissConfirmation', dismissConfirmation);
20+
contextBridge.exposeInMainWorld('confirmError', confirmationError);
21+
contextBridge.exposeInMainWorld('acceptConfirmation', acceptConfirmation);
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import Button from '@mui/material/Button'
2+
import Grid from '@mui/material/Grid'
3+
import Typography from '@mui/material/Typography'
4+
import AppWrapper from 'browser/components/AppWrapper'
5+
import renderWhenReady from 'browser/helpers/renderWhenReady'
6+
import React from 'react'
7+
8+
const Confirm = () => {
9+
// @ts-expect-error this exists
10+
const dismissConfirmation = () => window.dismissConfirmation()
11+
// @ts-expect-error this exists
12+
const acceptConfirmation = () => window.acceptConfirmation();
13+
14+
React.useEffect(() => {
15+
window.addEventListener('error', (e) => {
16+
// @ts-expect-error this exists
17+
window.confirmError(e.message)
18+
})
19+
window.addEventListener('keypress', (e) => {
20+
if (e.key === 'Enter') acceptConfirmation()
21+
else if (e.key === 'Escape') dismissConfirmation()
22+
})
23+
}, [])
24+
25+
return (
26+
<AppWrapper>
27+
<Grid className="centered pt-4" container spacing={1}>
28+
<Grid item xs={12}>
29+
<Typography id="confirm" variant="subtitle1" />
30+
</Grid>
31+
</Grid>
32+
<Grid className="centered" container spacing={1}>
33+
<Grid item xs={6}>
34+
<Button onClick={dismissConfirmation} variant="outlined">
35+
Cancel
36+
</Button>
37+
</Grid>
38+
<Grid item xs={6}>
39+
<Button onClick={acceptConfirmation} variant="contained">
40+
Confirm
41+
</Button>
42+
</Grid>
43+
</Grid>
44+
</AppWrapper>
45+
)
46+
}
47+
48+
renderWhenReady(Confirm)

packages/selenium-ide/src/browser/windows/PlaybackWindow/preload.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,20 @@ import { contextBridge, ipcRenderer, webFrame } from 'electron'
2525
// This is a hack to get around the fact that the prompt is not
2626
// available in the renderer process. This is a temporary solution
2727
const polyfill = () => {
28-
contextBridge.exposeInMainWorld(
29-
'prompt-polyfill',
30-
(question: string, defaultValue = '') => {
31-
const result = ipcRenderer.sendSync('prompt-polyfill', question, defaultValue)
32-
return result
33-
}
34-
)
35-
webFrame.executeJavaScript("window.prompt = window['prompt-polyfill'];")
28+
const keys = ['alert', 'confirm', 'prompt']
29+
keys.forEach((key) => {
30+
contextBridge.exposeInMainWorld(
31+
key + '-polyfill',
32+
(...args: any[]) => {
33+
const result = ipcRenderer.sendSync(
34+
key + '-polyfill',
35+
...args
36+
)
37+
return result
38+
}
39+
)
40+
webFrame.executeJavaScript(`window.${key} = window['${key}-polyfill'];`)
41+
})
3642
}
3743

3844
const recorderProcessors: RecorderPreprocessor[] = []
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { contextBridge, ipcRenderer } from "electron"
22

3-
function promptCancel() {
4-
ipcRenderer.send('prompt-cancel')
3+
function dismissPrompt() {
4+
ipcRenderer.send('dismiss-prompt')
55
}
66

77
function promptError(error: Error | string) {
@@ -12,10 +12,10 @@ function promptError(error: Error | string) {
1212
ipcRenderer.send('prompt-error', error)
1313
}
1414

15-
function promptSubmit(answer: string) {
16-
ipcRenderer.send('prompt-submit', answer)
15+
function answerPrompt(answer: string) {
16+
ipcRenderer.send('answer-prompt', answer)
1717
}
1818

19-
contextBridge.exposeInMainWorld('promptCancel', promptCancel);
19+
contextBridge.exposeInMainWorld('answerPrompt', answerPrompt);
20+
contextBridge.exposeInMainWorld('dismissPrompt', dismissPrompt);
2021
contextBridge.exposeInMainWorld('promptError', promptError);
21-
contextBridge.exposeInMainWorld('promptSubmit', promptSubmit);

packages/selenium-ide/src/browser/windows/Prompt/renderer.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import React from 'react'
1010
const Prompt = () => {
1111
const answerRef = React.useRef<HTMLInputElement>(null)
1212
// @ts-expect-error this exists
13-
const promptCancel = () => window.promptCancel()
13+
const dismissPrompt = () => window.dismissPrompt()
1414
// @ts-expect-error this exists
15-
const promptSubmit = () => window.promptSubmit(answerRef.current!.value);
15+
const answerPrompt = () => window.answerPrompt(answerRef.current!.value);
1616

1717
React.useEffect(() => {
1818
answerRef.current!.focus()
@@ -34,21 +34,21 @@ const Prompt = () => {
3434
id="answer"
3535
inputRef={answerRef}
3636
onKeyDown={(e) => {
37-
if (e.key === 'Enter') promptSubmit()
38-
else if (e.key === 'Escape') promptCancel()
37+
if (e.key === 'Enter') answerPrompt()
38+
else if (e.key === 'Escape') dismissPrompt()
3939
}}
4040
name="answer"
4141
size="small"
4242
/>
4343
</Stack>
4444
<Grid className="centered" container spacing={1}>
4545
<Grid item xs={6}>
46-
<Button onClick={promptCancel} variant="contained">
46+
<Button onClick={dismissPrompt} variant="outlined">
4747
Cancel
4848
</Button>
4949
</Grid>
5050
<Grid item xs={6}>
51-
<Button onClick={promptSubmit} variant="outlined">
51+
<Button onClick={answerPrompt} variant="contained">
5252
Submit
5353
</Button>
5454
</Grid>

0 commit comments

Comments
 (0)