Skip to content

Commit 810ff2b

Browse files
committed
Restoring a heap of functionaltiy:
type events record correctly side runner does persist session correctly (and lost a buncha code :D) added commands for requesting good selectors for coordinates modified base event listeners to be able to send back a response so we can ask the browser for stuff easier corrected step insert positioning removed sandbox parameter (turned out to be non-essential my b)
1 parent 0dc7e95 commit 810ff2b

File tree

22 files changed

+165
-199
lines changed

22 files changed

+165
-199
lines changed

packages/selenium-ide/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@seleniumhq/selenium-ide",
3-
"version": "4.0.0-alpha.57",
3+
"version": "4.0.0-alpha.58",
44
"private": true,
55
"description": "Selenium IDE electron app",
66
"author": "Todd <[email protected]>",
@@ -104,9 +104,8 @@
104104
"@seleniumhq/code-export-javascript-mocha": "^4.0.0-alpha.2",
105105
"@seleniumhq/code-export-python-pytest": "^4.0.0-alpha.2",
106106
"@seleniumhq/code-export-ruby-rspec": "^4.0.0-alpha.1",
107-
"side-code-export": "^4.0.0-alpha.11",
108107
"@seleniumhq/get-driver": "^4.0.0-alpha.1",
109-
"@seleniumhq/side-api": "^4.0.0-alpha.35",
108+
"@seleniumhq/side-api": "^4.0.0-alpha.36",
110109
"@seleniumhq/side-model": "^4.0.0-alpha.4",
111110
"@seleniumhq/side-runtime": "^4.0.0-alpha.31",
112111
"dnd-core": "^16.0.1",
@@ -120,6 +119,7 @@
120119
"react-dnd": "^16.0.1",
121120
"react-dnd-html5-backend": "^16.0.1",
122121
"react-dom": "^18.2.0",
122+
"side-code-export": "^4.0.0-alpha.11",
123123
"v8-compile-cache": "^2.3.0"
124124
},
125125
"devDependencies": {

packages/selenium-ide/src/browser/api/classes/EventListener.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { ipcRenderer } from 'electron'
22
import { BaseListener, VariadicArgs } from '@seleniumhq/side-api'
33

4-
54
const baseListener = <ARGS extends VariadicArgs>(
65
path: string
76
): BaseListener<ARGS> => {
@@ -14,7 +13,9 @@ const baseListener = <ARGS extends VariadicArgs>(
1413
},
1514
dispatchEvent(...args) {
1615
console.debug(path, 'dispatching event')
17-
listeners.forEach((fn) => fn(...args))
16+
const results = listeners.map((fn) => fn(...args))
17+
ipcRenderer.send(`${path}.response`, results)
18+
return results;
1819
},
1920
hasListener(listener) {
2021
return listeners.includes(listener)

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import preload from 'browser/helpers/preload'
2121
import { webFrame } from 'electron'
2222
import Recorder from './preload/recorder'
2323

24-
2524
(async () => {
2625
const plugins = await preload({
2726
recorder: api.recorder,

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
import { EventListenerParams, LocatorFields } from '@seleniumhq/side-api'
1919
import scrollIntoViewIfNeeded from 'scroll-into-view-if-needed'
20-
import {singleton as locatorBuilders} from './locator-builders'
20+
import { singleton as locatorBuilders } from './locator-builders'
2121
import TargetSelector from './target-selector'
2222

2323
const init = () => {
@@ -28,6 +28,9 @@ const init = () => {
2828
window.sideAPI.recorder.onHighlightElement.addListener(
2929
processHighlightCommand
3030
)
31+
window.sideAPI.recorder.onRequestElementAt.addListener(
32+
processElementAtCommand
33+
)
3134
window.addEventListener('beforeunload', () => {
3235
try {
3336
window.sideAPI.recorder.onRequestSelectElement.removeListener(
@@ -36,6 +39,9 @@ const init = () => {
3639
window.sideAPI.recorder.onHighlightElement.removeListener(
3740
processHighlightCommand
3841
)
42+
window.sideAPI.recorder.onRequestElementAt.removeListener(
43+
processElementAtCommand
44+
)
3945
} catch (e) {
4046
// ignore
4147
}
@@ -57,6 +63,17 @@ function processSelectionCommand(
5763
}
5864
}
5965

66+
function processElementAtCommand(
67+
x: number,
68+
y: number
69+
): [string, string][] | void {
70+
const element = document.elementFromPoint(x, y)
71+
if (element) {
72+
const target = locatorBuilders.buildAll(element as HTMLElement)
73+
return target
74+
}
75+
}
76+
6077
let targetSelector: TargetSelector | null = null
6178
function startSelection(field: LocatorFields) {
6279
targetSelector = new TargetSelector(function (element, win) {
@@ -99,7 +116,6 @@ function processMessage(event: MessageEvent<any>) {
99116

100117
async function processHighlightCommand(locator: string): Promise<void> {
101118
const element = await locatorBuilders.findElement(locator)
102-
console.log('Highlighting element', element)
103119
await highlight(element)
104120
}
105121

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ handlers.push([
9090
}
9191
this.recordingState.typeLock = 0
9292
},
93+
true,
9394
])
9495

9596
handlers.push([
@@ -98,6 +99,7 @@ handlers.push([
9899
function (this: Recorder, event) {
99100
this.recordingState.typeTarget = (event.target as HTMLElement) || null
100101
},
102+
true,
101103
])
102104

103105
// © Jie-Lin You, SideeX Team
@@ -151,7 +153,6 @@ handlers.push([
151153
function (this: Recorder, _event) {
152154
const event = _event as KeyboardEvent
153155
const target = event.target as HTMLInputElement
154-
console.log(event)
155156
if (target.tagName) {
156157
let key = event.keyCode
157158
let tagName = target.tagName.toLowerCase()

packages/selenium-ide/src/main/api/classes/EventListener.ts

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,28 @@
11
import { ipcMain, WebContents } from 'electron'
2-
import { BaseListener, EventMutator, ListenerFn, VariadicArgs } from '@seleniumhq/side-api'
2+
import {
3+
BaseListener,
4+
EventMutator,
5+
ListenerFn,
6+
VariadicArgs,
7+
} from '@seleniumhq/side-api'
38
import { Session } from 'main/types'
49
import getCore from '../helpers/getCore'
510
import { COLOR_CYAN, vdebuglog } from 'main/util'
611

712
const apiDebugLog = vdebuglog('api', COLOR_CYAN)
813

9-
const baseListener = <ARGS extends VariadicArgs>(
14+
export type MainListener<
15+
ARGS extends VariadicArgs,
16+
RESULT extends any
17+
> = BaseListener<ARGS> & {
18+
dispatchEventAsync: (...args: ARGS) => Promise<RESULT[][]>
19+
}
20+
21+
const baseListener = <ARGS extends VariadicArgs, RESULT extends any>(
1022
path: string,
1123
session: Session,
1224
mutator?: EventMutator<ARGS>
13-
): BaseListener<ARGS> => {
25+
): MainListener<ARGS, RESULT> => {
1426
const listeners: any[] = []
1527
return {
1628
addListener(listener) {
@@ -20,12 +32,25 @@ const baseListener = <ARGS extends VariadicArgs>(
2032
dispatchEvent(...args) {
2133
apiDebugLog('Dispatch event', path, args)
2234
if (mutator) {
35+
session.api.state.onMutate.dispatchEvent(path, args)
2336
const newState = mutator(getCore(session), args)
2437
session.projects.project = newState.project
2538
session.state.state = newState.state
39+
}
40+
return listeners.map((fn) => fn(...args))
41+
},
42+
async dispatchEventAsync(...args) {
43+
apiDebugLog('Dispatch event async', path, args)
44+
if (mutator) {
2645
session.api.state.onMutate.dispatchEvent(path, args)
46+
const newState = mutator(getCore(session), args)
47+
session.projects.project = newState.project
48+
session.state.state = newState.state
2749
}
28-
listeners.forEach((fn) => fn(...args))
50+
const results: RESULT[][] = await Promise.all(
51+
listeners.map((fn) => fn(...args))
52+
)
53+
return results;
2954
},
3055
hasListener(listener) {
3156
return listeners.includes(listener)
@@ -47,7 +72,7 @@ const wrappedListener = <ARGS extends VariadicArgs>(
4772
session: Session,
4873
mutator?: EventMutator<ARGS>
4974
) => {
50-
const api = baseListener<ARGS>(path, session, mutator)
75+
const api = baseListener<ARGS, any>(path, session, mutator)
5176
const senders: WebContents[] = []
5277
const senderCounts: number[] = []
5378
const senderFns: ListenerFn<ARGS>[] = []
@@ -74,14 +99,17 @@ const wrappedListener = <ARGS extends VariadicArgs>(
7499
senderCounts[index] += 1
75100
return
76101
}
77-
const senderFn = (...args: ARGS) => {
102+
const senderFn = (...args: ARGS) => new Promise((resolve) => {
78103
try {
104+
ipcMain.once(`${path}.response`, (_event, results) => {
105+
resolve(results)
106+
});
79107
sender.send(path, ...args)
80108
} catch (e) {
81109
// Sender has expired
82110
removeListener(event)
83111
}
84-
}
112+
});
85113
api.addListener(senderFn)
86114
senders.push(sender)
87115
senderCounts.push(1)

packages/selenium-ide/src/main/api/index.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { Api, processApi } from '@seleniumhq/side-api'
1+
import { Api, BaseListener, processApi } from '@seleniumhq/side-api'
22
import { Session } from 'main/types'
3-
import EventListener from './classes/EventListener'
3+
import EventListener, {MainListener} from './classes/EventListener'
44
import Handler from './classes/Handler'
55
import RawHandler from './classes/RawHandler'
66

@@ -11,7 +11,13 @@ export const overrides = {
1111
}
1212
} as const
1313

14-
export type MainApi = Api & {
14+
export type MainApi = {
15+
[NS in keyof Api]: {
16+
[K in keyof Api[NS]]: Api[NS][K] extends BaseListener<infer ARGS, infer RESULT>
17+
? MainListener<ARGS, RESULT>
18+
: Api[NS][K]
19+
}
20+
} & {
1521
recorder: {
1622
getWinHandleId: Session['recorder']['getWinHandleId']
1723
getFrameLocation: Session['recorder']['getFrameLocation']

packages/selenium-ide/src/main/session/controllers/Recorder/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,18 @@ export default class RecorderController extends BaseController {
141141
)
142142
}
143143

144+
async requestElementAt(x: number, y: number) {
145+
const results =
146+
await this.session.api.recorder.onRequestElementAt.dispatchEventAsync(
147+
x,
148+
y
149+
)
150+
const allResults = results.flat().flat().filter(Boolean);
151+
if (allResults.length) {
152+
return allResults[0]
153+
}
154+
}
155+
144156
async getWinHandleId(): Promise<string> {
145157
const session = await this.session.state.get()
146158
const activeTest = getActiveTest(session)

packages/selenium-ide/src/main/session/controllers/Windows/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,6 @@ export default class WindowsController extends BaseController {
199199
webPreferences: {
200200
// This should be the default preload, which just adds the sideAPI to the window
201201
preload: join(__dirname, `project-editor-preload-bundle.js`),
202-
sandbox: false,
203202
...(opts?.webPreferences ?? {}),
204203
},
205204
show: false,

packages/side-api/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@seleniumhq/side-api",
3-
"version": "4.0.0-alpha.35",
3+
"version": "4.0.0-alpha.36",
44
"private": false,
55
"description": "Selenium IDE API command shapes and such",
66
"author": "Todd Tarsi <[email protected]>",

0 commit comments

Comments
 (0)