-
Notifications
You must be signed in to change notification settings - Fork 5k
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
test: new switchToWindowWithTitle w/ Extension communication #25362
Changes from all commits
a55651a
5838ca3
11fb79a
ae10ca7
65c40e8
5deb0c4
5ea1bc5
72b3222
41c9eaf
c9dc9f7
e290160
299ce1a
fbeb1a4
abaa36a
c745464
0f4e1d1
0232641
99754f2
7b675af
3779eee
c611652
d6adad6
09533c6
8b9b1a4
bef19fe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import events from 'events'; | ||
import { WebSocketServer } from 'ws'; | ||
import { | ||
MessageType, | ||
ServerMochaEventEmitterType, | ||
WindowProperties, | ||
} from './types'; | ||
|
||
/** | ||
* This singleton class runs on the Mocha/Selenium test. | ||
* It's used to communicate from the Mocha/Selenium test to the Extension background script (service worker in MV3). | ||
*/ | ||
class ServerMochaToBackground { | ||
private server: WebSocketServer; | ||
|
||
private ws: WebSocket | null = null; | ||
|
||
private eventEmitter; | ||
|
||
constructor() { | ||
this.server = new WebSocketServer({ port: 8111 }); | ||
|
||
console.debug('ServerMochaToBackground created'); | ||
|
||
this.server.on('connection', (ws: WebSocket) => { | ||
// Check for existing connection and close it | ||
if (this.ws) { | ||
console.error( | ||
'ServerMochaToBackground got a second client connection, closing the first one', | ||
); | ||
this.ws.close(); | ||
} | ||
|
||
this.ws = ws; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wonder if we should guard against multiple connection attempts 🤔. Maybe not, just a thought. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm so that would happen if you accidentally ran two E2E tests at the same time? Yeah we should check what happens. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or devs might just try to do some weird things with this API There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Second connection disconnects the first, and also stopped the Extension from connecting if it isn't being controlled by Selenium |
||
|
||
console.debug('ServerMochaToBackground got a client connection'); | ||
|
||
ws.onmessage = (ev: MessageEvent) => { | ||
let message: MessageType; | ||
|
||
try { | ||
message = JSON.parse(ev.data); | ||
} catch (e) { | ||
throw new Error( | ||
`Error in JSON sent to ServerMochaToBackground: ${ | ||
(e as Error).message | ||
}`, | ||
); | ||
} | ||
|
||
this.receivedMessage(message); | ||
}; | ||
|
||
ws.onclose = () => { | ||
this.ws = null; | ||
console.debug('ServerMochaToBackground disconnected from client'); | ||
}; | ||
}); | ||
|
||
this.eventEmitter = new events.EventEmitter<ServerMochaEventEmitterType>(); | ||
} | ||
|
||
// This function is never explicitly called, but in the future it could be | ||
stop() { | ||
this.ws?.close(); | ||
|
||
this.server.close(); | ||
|
||
console.debug('ServerMochaToBackground stopped'); | ||
} | ||
|
||
// Send a message to the Extension background script (service worker in MV3) | ||
send(message: MessageType) { | ||
if (!this.ws) { | ||
throw new Error('No client connected to ServerMochaToBackground'); | ||
} | ||
|
||
this.ws.send(JSON.stringify(message)); | ||
} | ||
|
||
// Handle messages received from the Extension background script (service worker in MV3) | ||
private receivedMessage(message: MessageType) { | ||
if (message.command === 'openTabs' && message.tabs) { | ||
this.eventEmitter.emit('openTabs', message.tabs); | ||
} else if (message.command === 'notFound') { | ||
throw new Error( | ||
`No window found by background script with ${message.property}: ${message.value}`, | ||
); | ||
Comment on lines
+86
to
+88
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Logic: Throwing an error here might cause the entire test suite to fail. Consider handling this more gracefully or providing more context. |
||
} | ||
} | ||
|
||
// This is not used in the current code, but could be used in the future | ||
queryTabs(tabTitle: string) { | ||
this.send({ command: 'queryTabs', title: tabTitle }); | ||
} | ||
|
||
// Sends the message to the Extension, and waits for a response | ||
async waitUntilWindowWithProperty(property: WindowProperties, value: string) { | ||
this.send({ command: 'waitUntilWindowWithProperty', property, value }); | ||
|
||
const tabs = await this.waitForResponse(); | ||
// console.debug('ServerMochaToBackground got the response', tabs); | ||
|
||
// The return value here is less useful than we had hoped, because the tabs | ||
// are not in the same order as driver.getAllWindowHandles() | ||
return tabs; | ||
} | ||
|
||
// This is a way to wait for an event async, without timeouts or polling | ||
async waitForResponse() { | ||
return new Promise((resolve) => { | ||
this.eventEmitter.once('openTabs', resolve); | ||
}); | ||
} | ||
} | ||
|
||
// Singleton setup below | ||
let _serverMochaToBackground: ServerMochaToBackground; | ||
|
||
export function getServerMochaToBackground() { | ||
if (!_serverMochaToBackground) { | ||
startServerMochaToBackground(); | ||
} | ||
|
||
return _serverMochaToBackground; | ||
} | ||
|
||
function startServerMochaToBackground() { | ||
_serverMochaToBackground = new ServerMochaToBackground(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logic: Potential issue with handling multiple WebSocket connections. Consider adding logic to manage multiple connections more gracefully.