-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[dotnet] #10161 Allow new targets to wait until debugger is attached #10603
Conversation
…awaiting multiple commands at once.
Thanks for the contribution. I'm not very experienced in either C# or in DevTools, but I'm trying to help out more in this part of the codebase, so a few things:
|
Thanks for your response. The changes I made are mimicking the behavior of Puppeteer (https://github.com/puppeteer/puppeteer) and (https://github.com/microsoft/playwright).
However in the current implementation invoking the runtime.runIfWaitingForDebugger should be done by the one implementing Selenium into his code. For instance this is the code I use for that in my own codebase;
This might not be ideal for everyone just wanting an out of the box solution when consuming the nuget package. We could also look towards having a default implementation for this, but allowing an override to support for advanced scenarios.
|
Hi, Did you have any change to look at my reply? With kind regards |
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.
Thanks for answering my questions, I understand this (a bit) better now.
Ideally there would be exhaustive tests showing how existing code works, and then you could add some tests showing how new code works. As it is, the tests we have that I can get to run aren't exercising the code you're changing, and I can't tell if the public tasks changing parameters is breaking existing functionality that users might currently use be relying on. Do we need to add a task instead of changing it for backwards compatibility?
Also, this needs to be rebased on the latest trunk for the versioned targets. Thanks.
/// <summary> | ||
/// Initializes a new instance of the DevToolsSession class, using the specified WebSocket endpoint. | ||
/// </summary> | ||
/// <param name="endpointAddress"></param> | ||
public DevToolsSession(string endpointAddress) | ||
/// <param name="waitForDebuggerOnStart">When enabled new targets will be waiting until runtime.runIfWaitingForDebugger is invoked.</param> | ||
public DevToolsSession(string endpointAddress, bool waitForDebuggerOnStart) |
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.
should waitForDebuggerOnStart
remain an optional parameter for backwards compatibility?
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.
I think you are right on this one, I will make a commit for this.
@@ -194,7 +201,7 @@ public async Task<ICommandResponse<TCommand>> SendCommand<TCommand>(TCommand com | |||
/// <param name="throwExceptionIfResponseNotReceived"><see langword="true"/> to throw an exception if a response is not received; otherwise, <see langword="false"/>.</param> | |||
/// <returns>The command response object implementing the <see cref="ICommandResponse{T}"/> interface.</returns> | |||
//[DebuggerStepThrough] | |||
public async Task<JToken> SendCommand(string commandName, JToken commandParameters, CancellationToken cancellationToken = default(CancellationToken), int? millisecondsTimeout = null, bool throwExceptionIfResponseNotReceived = true) | |||
public async Task<DevToolsCommandResponse> SendCommand(DevToolsCommandSettings devToolsCommandSettings, CancellationToken cancellationToken = default(CancellationToken), int? millisecondsTimeout = null, bool throwExceptionIfResponseNotReceived = true) |
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.
Is this change backwards compatible?
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.
I've re-introduced this public function to be backwards compatible.
/// <param name="cancellationToken">A CancellationToken object to allow for cancellation of the command.</param> | ||
/// <param name="millisecondsTimeout">The execution timeout of the command in milliseconds.</param> | ||
/// <param name="throwExceptionIfResponseNotReceived"><see langword="true"/> to throw an exception if a response is not received; otherwise, <see langword="false"/>.</param> | ||
/// <returns>The command response object implementing the <see cref="ICommandResponse{T}"/> interface.</returns> | ||
Task<JToken> SendCommand(string commandName, JToken @params, CancellationToken cancellationToken, int? millisecondsTimeout, bool throwExceptionIfResponseNotReceived); | ||
Task<DevToolsCommandResponse> SendCommand(DevToolsCommandSettings devToolsCommandSettings, CancellationToken cancellationToken, int? millisecondsTimeout, bool throwExceptionIfResponseNotReceived); |
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.
Is this backwards compatible?
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.
I've re-introduced this public function to be backwards compatible.
I think this is not needed anymore given the DevTools revamp in .NET, right @nvborisenko? |
@diemol, I quickly walked through this and, seems, this is still actual, and the issue is more global in Selenium across all bindings. I am not expert in CDP, but it looks like Puppeteer and Playwright really use As I understood we can reproduce it via:
|
This is CDP only, I guess we need to decide if we want to work on this or focus on BiDi. |
You are right about this issue still being actual. Like you said, Selenium is not able to monitor the network in time when opening a new tab in it's current setup. Usually the first navigate after opening a tab will be missing because the network domain is not enabled yet. To accomplish this a couple of things needs to happen;
One tricky thing is that Chromium also halts all commands for a specific target until Runtime.runIfWaitingForDebugger is invoked. Because of this I introduced the SendCommands function which is able to send multiple commands without them blocking eachother. We might be able to get rid of the SendCommands function because of your changes, but I haven't tested this yet.
What do you think about this? I can rebase the PR and try to get it to work without the SendCommands function. |
We have an in-person working session in 2 weeks and an important piece of that will be to improve the .NET/Windows build experience. |
@EdwinVanVliet if you are interested in the implementation, please go ahead. I see you do :) From my perspective we can split this work to smaller slices:
It would be easier for all us to land the fix step by step (separate PRs?).
|
Thanks for contributing to Selenium!
A PR well described will help maintainers to quickly review and merge it
Before submitting your PR, please check our contributing guidelines.
Avoid large PRs, help reviewers by making them as simple and short as possible.
Description
-Added TargetAttached event to Target domain in order to allow consumers of DevTools session to be informed about new targets.
-Added SendCommands function to DevToolsSession. This function is needed when using the Runtime.runIfWaitingForDebugger command in conjuntion with other commands. Using the singular SendCommand function will result in blocking issues.
-Added waitForDebugger argument to InitializeSession function DevToolsSession to enable/disable waiting for the debugger to attach. By default it's disabled because that's current behavior.
Motivation and Context
When a new target (new tab for instance) is created DevTools continues execution based on the WaitForDebugger property set in the SetAutoAttach feature. When the WaitForDebugger property is set to false DevTools continues without waiting the consumer to properly enable all domains on the target. For instance when being interested in network events from the network domain we need to invoke Network.enable for that specific target. The current behavior causes some of the network events to be missing due to Selenium enabling the domains after the target already performed network requests.
By allowing consumers to enable the WaitForDebugger property we can enable all domains and tell DevTools whenever we are ready by using the Run.runIfWaitingForDebugger command.
Types of changes
Checklist