spectron
spectron copied to clipboard
Client is not accessing second window. Is it possible?
I have an app that opens first window, does a little thing, closes the first window, and opens the second one.
When in the first window, all client APIs work.
But when in the second one, app.client.getHTML('body')
throws
Stack:
RuntimeError: no such window: target window already closed
from unknown error: web view not found
at execute(<Function>) - selectorExecute.js:97:75
at execute("return !!document.evaluate;") - ensureClientSideSelectorSupport.js:23:17
Is it possible at all to web-drive the second window?
Note that in both cases, app.client.getWindowCount()
produces 1
, as only one window is open, and app.client.windowHandles()
changes as well.
Can a handle be used to redirect client to a new window? Or, something like this.
It is possible to redirect client to other window by "focusing" function app.client.windowByIndex(0)
But:
- There is a bug. After this refocusing of client on a different window, console's calls in
app.client.execute()
andapp.client.executeAsync()
are not showing in a list of all logs from renderer. - Is this refocusing of client a point of
app.client.windowByIndex(0)
? And if so, we should highlight it in the doc. See #88
Would it be better to rename app.client.windowByIndex(...)
to app.client.targetWindowByIndex(...)
, or to app.client.targetWindow(...)
?
I'm experiencing a similar issue in a multi-window app. Would be great to see better support for this.
I'm not sure I see the issue here. You are initially targeting Window A. You close Window A and open Window B and suddenly you expect it to be pointing to Window B instead?
You need to call
app.client.windowByIndex(0)
To refocus onto the new window (The 0 index thing is a bit misleading) but when you think about it it makes sense.
Yes, @MarshallOfSound . Quote, _The 0 index thing is a bit misleading_, needs to change.
It would be wonderful to have targeting methods to use some unique identifiers from handlers, enumerated by app.client.windowHandles()
, and be able in code to say window A, window B, etc., and .targetWindow()
with such unique ids.
It would also be wonderful to have a method 'app.client.targetedWindow()` that produces such identifier for a currently targeted window.
The unique ID's are in the values
property of app.client.windowHandles()
and you can call app.client.window(windowHandleValue)
to focus a different window.
Don't forget we have full access to WebDriver IO methods.
http://webdriver.io/api/protocol/window.html
So you could do this yourself with.
app.client.windowHandles()
.then((handles) => {
const windowA = handles.values[0];
const windowB = handles.values[1];
// app.client.window(windowA); <-- Will focus windowA
// app.client.window(windowB); <-- Will focus windowB
});
Most of what spectron does is expose the WebDriver methods and the Electron methods in the same object to make testing ridiculously easy. Lots of the power / methods you are asking for is already part of the WebDriver methods.
@MarshallOfSound now you are talking business! There is even a current target/handle available! client.windowHandle(). Although, in docs we should mention that it is WebDriver's API that deals with multiple windows/tabs.
Thus, the only unresolved point from this issue is a bug with console:
After this refocusing of client on a different window, console's calls in
app.client.execute()
andapp.client.executeAsync()
are not showing in a list of all logs from renderer.
app.client.windowHandles() .then((handles) => { //const windowA = handles.values[0]; // throwing error "can not read property 0 of undefined". //const windowB = handles.values[1]; // Its a typo I guess, value is the correct field not values
const windowA = handles.value[0];
const windowB = handles.value[0];
app.client.window(windowA).click('#elementIdA'); // will click element of windowA
app.client.window(windowB).click('#elementIdB'); // will click element of windowB
});
app.client.window
is not exists...
I can get
[
'CDwindow-3A94A50FD4E46F979A459297ECFF60D4',
'CDwindow-4E0C8E41B579F69C850DEC94861CC0B3'
]
from const handles = await this.app?.client?.getWindowHandles();
but how to get actual window handle, and do window.$(selector)
?