-
Notifications
You must be signed in to change notification settings - Fork 42
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
Add support for custom browser to client messages #361
Conversation
46ea849
to
2e9170a
Compare
There are a couple of open issues around the proposed change to make preload scripts work like
So I think there are a few options:
I think I prefer Option 2, but it does restrict the use cases somewhat. For example you can't open a page, then install a preload script, with a |
@jgraham there is one other question that I have. In regards of the usage for Selenium I think that they also wanted to have the possibility to install such a script that then can be re-used to not have to send the specific atoms for each and every eg. element displayed check. How would this actually work with the |
Something like: webdriver.installPreloadScript(
() => {
window.isDisplayed = element => {
// Implementation
}
},
sandbox="selenium-internal") and then later webdriver.callFunction(elem => isDisplayed(elem), arguments=[element], context=contextId, sandbox="selenium-internal") |
I see. So the |
de1adbb
to
5220668
Compare
The Browser Testing and Tools Working Group just discussed The full IRC log of that discussion<jgraham> Topic: Pre-load script - support for custom browser to client messages<jgraham> Github: https://github.com//pull/361 <orkon> jgraham (IRC): in December, we discussed how to implement sending custom messages from the browser to the client. We should implement by having a special type that serialised to a function that is when called sends a message. We have not considered how it interacts with preload scripts. But preload scripts don't accept arguments. We then thought we can convert scripts to functions. But there are some problems (see the issue). <orkon> jgraham (IRC): when you have arguments, you can pass any argument and provide a handle to an object but it does not exist in the preload script, so it fails every time the preload script runs. <orkon> jgraham (IRC): currently they are JS errors but actually are preload errors <orkon> jgraham (IRC): we have a couple of options 1) don't care about return values 2) throw a JS exception for arguments 3) or we can only have arguments that can be serialzed statically, no shared references <orkon> jgraham (IRC): there could be cases where shared references are needed but they are fragile <orkon> jgraham (IRC): there could be also events for the results of the preload scripts <jgraham> q? <JimEvans> q+ <jgraham> ack JimEvans <sadym> q+ <orkon> Jim Evans: I like the idea of being able to know the result of the preload result if we change them to be functions. I like an idea for the event containing a result or an error. But the clients don't need to subscribe to the event, if they don't need to. <orkon> Jim Evans: how does the remote end needs to do to raise the event? <orkon> jgraham (IRC): it deserialises to a function and the function emits the event <jgraham> ack sadym <orkon> jgraham (IRC): it doest the impl magic to make the event emitte <orkon> s/emitte/emitted/ <jgraham> q+ <orkon> sadym (IRC): arguments and events as the result sound reasonable. We can consider rolling back to the option with allowing only channels because the use case when we want to reuse the sharedId seems artificial. But it sounds like a slippery road to provide this functionality. <jgraham> ack jgraham <orkon> jgraham (IRC): I think I agree with that. Realistically, passing primitive values does not make much sense. Passing sharedId only works in limited circumstances if you know that all preload scrips are in the same origin but I don't have a use case. <orkon> jgraham (IRC): my concern with the event is: obviously running a preload script can cause an exception and we emit it as a js error and you need to listen for log events to find that out. On other hand, if we had a specific event, then you kind of have to subscribe to it. E.g., if you had a bug where a preload script does not work, you would not know. <orkon> jgraham (IRC): perhaps we could parse the script early but not runtime exceptions <orkon> jgraham (IRC): I think none of the tradeoffs are great actually <jgraham> q? <sadym> q+ <orkon> jgraham (IRC): I think I am going to try implementing changes in the PR to be the option: it is still a function, can accept only channels as args and all exceptions are js exceptions. If it is not an option, mention this now or comment on the issue. <jgraham> ack sadym <orkon> sadym (IRC): what other option do we have if we rollback from callFunction to evaluate where there was a global handle to raise the event. <orkon> jgraham (IRC): I believe that does not solve any problems that channels don't solve <orkon> jgraham (IRC): no reason to prefer globals over channels <JimEvans> q+ <jgraham> ack JimEvans <orkon> Jim Evans: looked at the print PR, nothing controversial. <jgraham> RRSAgent: make minutes <RRSAgent> I have made the request to generate https://www.w3.org/2023/02/08-webdriver-minutes.html jgraham <jgraham> Zakim, bye <Zakim> leaving. As of this point the attendees have been JimEvans, orkon, brwalder, whimboo, jgraham, patrickangle_, Sasha, jdescottes, sadym, simons <jgraham> RRSAgent: bye <RRSAgent> I see 1 open action item saved in https://www.w3.org/2023/02/08-webdriver-actions.rdf : <RRSAgent> ACTION: whimboo to file a BiDi issue covering this scenario [1] <RRSAgent> recorded in https://www.w3.org/2023/02/08-webdriver-irc#T17-33-21 <JimEvans> jgraham: I'm evidently quite dense, because I'm still not quite getting how the message for a preload script would get raised. Is it as simple as the function definition being something like `(channel) => channel = document.title;` for example? And that would send the title back in the script.message event? |
b2543f2
to
577ae33
Compare
I updated this as follows:
One quality of life improvement we could make would be to return an error to the command if the script can't be evaluated as a function body. The question is where that evaluation happens e.g. if I pass in |
index.bs
Outdated
@@ -1529,6 +1530,9 @@ To <dfn>deserialize local value</dfn> given |local protocol value|, |realm| and | |||
1. If |local protocol value| matches the [=PrimitiveProtocolValue=] production, return | |||
[=deserialize primitive protocol value=] with |local protocol value|. | |||
|
|||
1. If |local protocol value| matches the <code>script.Channel</code> production, |
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.
Can we pick other naming, as channel
is already used in out implementation-specific extension for other purpose?
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.
The precedent is the use of the word "Channel" for the same concept basically everywhere else on the platform e.g. MessageChannel
, BroadcastChannel
, etc.
7c1d66d
to
b6daf91
Compare
To help with reviewing, I've split the preload script changes out into #381 and made this PR just about the addition of the message channel. This PR is based on that one, so it needs to merge first. |
06112ca
to
0613ecb
Compare
@sadym-chromium Are you happy with the most recent changes here? I’d really like to get this merged, if there is consensus that it’s ready. |
43cb9d3
to
7425997
Compare
This adds a Channel type that can be deserialized as a script argument. On the wire the argument looks like: { "type": "channel", "value": { "channel": "my-message-channel", "ownership": "root" } } On deserialization this is turned into a function that when called with an argument emits a `script.message` event containing the channel name and the serialized value of the first argument to the function (using a single argument to allow future extensions and because it's close to `postMessage`). This should meet the usecase of allowing client-defined events that are implemented in script e.g. for mutation events.
This introduces a
script.Channel
type which deserializes to a function that when called sends ascript.message
event with its first argument.It also changes preload scripts to work as functions rather than just being evaluated directly. This allows arguments to be passed in particuarly for the use of channels so that preload scripts can install event listeners that message back to the client.
Preview | Diff