Skip to content
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

Empty logs for Selenium 4 alpha 5 when using RemoteWebdriver #8229

Closed
szamacz opened this issue Mar 27, 2020 · 14 comments
Closed

Empty logs for Selenium 4 alpha 5 when using RemoteWebdriver #8229

szamacz opened this issue Mar 27, 2020 · 14 comments

Comments

@szamacz
Copy link

szamacz commented Mar 27, 2020

🐛 Bug Report

A clear and concise description of what the bug is.

When using latest Selenium 4 image with RemoteWebdriver and chrome standalone 4.0.0-alpha-5-20200326 docker image all kind of logs are empty. Problem does not exists in case of using local chrome browser (ver 80.0.3987.149 ).

To Reproduce

  1. Run standalone chrome docker image from docker hub with selenium 4
  2. Run tests against image using RemoteWebdriver
  3. Get logs
    AvailableLogTypes count returns 0

Detailed steps to reproduce the behavior:

Expected behavior

There should be 5 types of logs, and at least 2 of them shouldn't be empty (Browser and Driver) - like in case of running this against regular Chrome browser.

Test script or set of commands reproducing this issue

public class RemoteWebriverTests : IDisposable
{
    private readonly IWebDriver _driver;

    public RemoteWebriverTests()
    {
        var chromeOptions = new ChromeOptions();
        _driver = new RemoteWebDriver(new Uri("http://localhost:4444/"), chromeOptions);
    }

    [Fact]
    public void GetLogsFromChrome()
    {
        _driver.Navigate().GoToUrl("http://www.youtube.com");
        Thread.Sleep(5000);
        Assert.True(_driver.Manage().Logs.AvailableLogTypes.Count > 0);
    }

    public void Dispose()
    {
        _driver.Quit();
    }
}

Environment

OS: Windows 10
Browser: Chrome
Browser version: 80.0.3987.149
Docker image version: 4.0.0-alpha-5-20200326
Browser Driver version: 80.0.3987.10600
Language Bindings version: .net core 3.1
Selenium Grid version : 4.0.0-alpha-5

@diemol diemol transferred this issue from SeleniumHQ/selenium Mar 27, 2020
@szamacz
Copy link
Author

szamacz commented Apr 21, 2020

Issue reproducible also on standalone-chrome:4.0.0-alpha-5-20200409

@diemol diemol transferred this issue from SeleniumHQ/docker-selenium Apr 22, 2020
@ghost ghost added the needs-triaging label Apr 22, 2020
@szamacz
Copy link
Author

szamacz commented Jun 11, 2020

Issue reproducible also on version 4.0.0-alpha6-20200609. Are there any plans to look at this?

@barancev
Copy link
Member

Works for me with docker image selenium/standalone-chrome:4.0.0-alpha6-20200609 and java binding 4.0.0-alpha6, so it must be something .Net specific.

@barancev
Copy link
Member

Yes, reproduced with .Net binding 4.0.0-alpha05 and the abovementioned docker image

@JunTaoLuo
Copy link

Hey @barancev we are running into this problem as well in our test environment. In fact, with Chrome 85, we had to update to a newer version of Selenium and ended up running into this bug. Is there any plans on addressing this soon?

@john1506
Copy link

this is also affecting us - would just like to chime in

pranavkm added a commit to dotnet/aspnetcore that referenced this issue Sep 24, 2020
Seleniunm currently does not return log messages (See SeleniumHQ/selenium#8229).
This making figuring out blazor WASM test failures a lot harder.

This change adds some JS to the test apps to read the console output.
wtgodbe pushed a commit to dotnet/aspnetcore that referenced this issue Sep 29, 2020
* Attempt to read the logs from the browser

Seleniunm currently does not return log messages (See SeleniumHQ/selenium#8229).
This making figuring out blazor WASM test failures a lot harder.

This change adds some JS to the test apps to read the console output.

* WIP
@Dreamescaper
Copy link

Problem is that RemoteWebDriver does not implement marker interface ISupportsLogs, and without it it doesn't even try to get those logs (https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/Remote/RemoteLogs.cs#L50).

Currently we use the following workaround:

        private static ConcurrentDictionary<IWebDriver, ICommandExecutor> _commandExecutors = new ConcurrentDictionary<IWebDriver, ICommandExecutor>();

        private static List<LogEntry> GetLogs(IWebDriver webDriver)
        {
            // Workaround for bug https://github.com/SeleniumHQ/selenium/issues/8229 .
                if (!_commandExecutors.TryGetValue(webDriver, out var commandExecutor))
                {
                    commandExecutor = (ICommandExecutor)typeof(RemoteWebDriver)
                        .GetProperty("CommandExecutor", BindingFlags.NonPublic | BindingFlags.Instance)
                        .GetValue(webDriver);

                    commandExecutor.CommandInfoRepository.TryAddCommand(DriverCommand.GetAvailableLogTypes, new CommandInfo(CommandInfo.GetCommand, "/session/{sessionId}/se/log/types"));
                    commandExecutor.CommandInfoRepository.TryAddCommand(DriverCommand.GetLog, new CommandInfo(CommandInfo.PostCommand, "/session/{sessionId}/se/log"));

                    _commandExecutors[webDriver] = commandExecutor;
                }

                var response = commandExecutor.Execute(new Command(((IHasSessionId)webDriver).SessionId, DriverCommand.GetLog, new Dictionary<string, object> { ["type"] = "browser" }));

                var fromDictionaryMethod = typeof(LogEntry).GetMethod("FromDictionary", BindingFlags.Static | BindingFlags.NonPublic);
                var logEntries = ((IEnumerable<object>)response.Value)
                    .Select(v => fromDictionaryMethod.Invoke(null, new[] { v }))
                    .OfType<LogEntry>()
                    .ToList();

                return logEntries;
        }

@szamacz
Copy link
Author

szamacz commented Oct 20, 2020

Thanks @Dreamescaper your workaround works perfectly

@SteveSandersonMS
Copy link

What seems like a simpler workaround to me is the following. Subclass RemoteWebDriver with your own class that implements the ISupportsLogs interface, and then use that instead of new RemoteWebDriver(...). For example:

private class RemoteWebDriverWithLogs : RemoteWebDriver, ISupportsLogs
{
    // Also pass through any constructors you want to use
}

It makes our tests work again.

@szamacz
Copy link
Author

szamacz commented Sep 7, 2021

Workaround for version 4 RC1

private static ConcurrentDictionary<IWebDriver, ICommandExecutor> _commandExecutors = new ConcurrentDictionary<IWebDriver, ICommandExecutor>();

        private static List<LogEntry> GetLogs(IWebDriver webDriver)
        {
            // Workaround for bug https://github.com/SeleniumHQ/selenium/issues/8229 .
                if (!_commandExecutors.TryGetValue(webDriver, out var commandExecutor))
                {
                    commandExecutor = (ICommandExecutor)typeof(RemoteWebDriver)
                        .GetProperty("CommandExecutor", BindingFlags.Public | BindingFlags.Instance)
                        .GetValue(webDriver);

                    commandExecutor.TryAddCommand(DriverCommand.GetAvailableLogTypes, new HttpCommandInfo(HttpCommandInfo.GetCommand, "/session/{sessionId}/se/log/types"));
                    commandExecutor.TryAddCommand(DriverCommand.GetLog, new HttpCommandInfo(HttpCommandInfo.PostCommand, "/session/{sessionId}/se/log"));

                    _commandExecutors[webDriver] = commandExecutor;
                }

                var response = commandExecutor.Execute(new Command(((IHasSessionId)webDriver).SessionId, DriverCommand.GetLog, new Dictionary<string, object> { ["type"] = "browser" }));

                var fromDictionaryMethod = typeof(LogEntry).GetMethod("FromDictionary", BindingFlags.Static | BindingFlags.NonPublic);
                var logEntries = ((IEnumerable<object>)response.Value)
                    .Select(v => fromDictionaryMethod.Invoke(null, new[] { v }))
                    .OfType<LogEntry>()
                    .ToList();

                return logEntries;
        }

@Bakanych
Copy link

Any chance to fix that?

@titusfortner
Copy link
Member

You should be able to directly subclass this and just add ISupportsLogs without having to futz with the command executor. Which is probably the best right answer.

public class RemoteChromeDriver : RemoteWebDriver, ISupportsLogs

That said, this should be easier. Jim created the Custom Driver Command Executor class for adding browser-specific functionality like this (https://titusfortner.com/2022/03/10/custom-executor.html)

Except just adding the commands isn't enough because there is no way to allow the RemoteDriver to implement ISupportsLogs. Every option I can think to allow it is either hacky or not backwards compatible.

I'll PR something and see if it is the least hacky way to support it.

@titusfortner
Copy link
Member

This will work with Selenium 4.2:

driver = new RemoteWebDriver(new Uri(address), new ChromeOptions());

IReadOnlyDictionary<string, CommandInfo> logCommands = new Dictionary<string, CommandInfo>
{
    {
        DriverCommand.GetAvailableLogTypes,
        new HttpCommandInfo(HttpCommandInfo.GetCommand, "/session/{sessionId}/se/log/types")
    },
    {
        DriverCommand.GetLog,
        new HttpCommandInfo(HttpCommandInfo.PostCommand, "/session/{sessionId}/se/log")
    }
};

var customCommandDriver = driver as ICustomDriverCommandExecutor;
customCommandDriver.RegisterCustomDriverCommands(logCommands);

ReadOnlyCollection<string> logTypes = driver.Manage().Logs.AvailableLogTypes;

Assert.That(logTypes, Is.Not.Empty);

driver.Url = "https://selenium.dev/selenium/web/errors.html";
driver.FindElement(By.CssSelector("input")).Click();

ReadOnlyCollection<LogEntry> entries = driver.Manage().Logs.GetLog("browser");

Assert.That(entries, Is.Not.Empty);

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked and limited conversation to collaborators Jun 25, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

9 participants