operasoftware / operachromiumdriver

OperaDriver for Chromium-based Opera releases
Other
261 stars 47 forks source link

find_element returning dictionary instead of WebElement in python-selenium #96

Open Garakusi opened 3 years ago

Garakusi commented 3 years ago

Tested with geckodriver and chromedriver, only happens with operadriver. Requested url: https://ifconfig.me Code: driver.find_element("id", "ip_address") Return: {'ELEMENT': '0.9986878751861266-1'} The value for ELEMENT always changes. Selenium: 4.0.0 Opera: 80.0.4170.40 Operadriver: 94.0.4606.61 OS: Arch Linux

SadSack963 commented 2 years ago

I have the latest Opera version 81.0.4196.37, webdriver version 95.0.4638.54, and suffering the same issue.

According to this page: What Is New In Selenium 4 And What Is Deprecated In It?

The native support for Opera and PhantomJS is removed in Selenium 4, as their WebDriver implementations are no longer under development. The Opera browser is based on Chromium, and users looking to test their implementation on Opera can opt for testing on the Chrome browser. PhantomJS users can opt for testing on Firefox and Chrome in the headless mode.

See v4.0.0-alpha.1

A similar issue was also raised on the Selenium Github, though it has been closed there: [🐛 Bug]: FIND_ELEMENT command return a dict object value #9978 , Also bug #10025.

rkrupski commented 2 years ago

Hi, using Selenium 4.0.0 with the latest operadriver v.96.0.4664.45 (Opera 82) try to apply additional option wc3=True when instantiating the driver.

Here is a snippet for Python:

options = webdriver.ChromeOptions() options.add_experimental_option('w3c', True) driver = webdriver.Opera(options=options)

b-adiguzel44 commented 2 years ago

Hi, using Selenium 4.0.0 with the latest operadriver v.96.0.4664.45 (Opera 82) try to apply additional option wc3=True when instantiating the driver.

Here is a snippet for Python:

options = webdriver.ChromeOptions() options.add_experimental_option('w3c', True) driver = webdriver.Opera(options=options)

Hello there sir, I'm currently using Selenium 4.1.3 with the latest opera driver v.99.0.4844.51 (Opera 85). I was getting AttributeError: 'dict' object has no attribute 'click' from driver.find_element(by=By.XPATH, value="xpath_value").click() method and your solution has fixed my problem.

titusfortner commented 2 years ago

The right way to use Opera in Selenium 4.2+ is to use ChromeOptions and pass in the location to the opera browser. Please do not include the w3c parameter.

See relevant language examples here: https://www.selenium.dev/documentation/webdriver/getting_started/open_browser/#opera

The lack of updates to this project and not getting a response to issue #88 led us to choose to remove direct support. Chromedriver will successfully drive Opera in the required protocol.

mialeska commented 2 years ago

Found a solution unexpectedly by comparing java and dotnet implementation and documentation on selenium.dev. Solution was to prepare proper ChromeOptions: 1) set binary to location of launcher.exe 2) set start arguments: "--remote-debugging-port=9222", "--no-sandbox", "--disable-dev-shm-usage" 3) ! force set "w3c" to true. In java this is quite simple: options.setExperimentalOption("w3c", true); In C# such capability is forbidden as already known, so I had to use the reflection to forcibly add it to additionalChromeOptions private dictionary in ChromiumOptions class:

            var field = typeof(ChromiumOptions).GetField("additionalChromeOptions", BindingFlags.NonPublic | BindingFlags.Instance);
            if (field.GetValue(options) is Dictionary<string, object> optionsDictionary)
            {
                optionsDictionary["w3c"] = true;
                field.SetValue(options, optionsDictionary);
            }
            options.BinaryLocation = BinaryLocation;

4) You need to use operadriver executable, not the chromedriver. You can check out the latest operadriver here: https://github.com/operasoftware/operachromiumdriver/releases . And you need to tell the ChromeDriver that you're using it when instantiating.

    var driver = new ChromeDriver(ChromeDriverService.CreateDefaultService(driverDir, "operadriver.exe"), options);

Hope this would help to somebody else =)

I'm working now on integration of these actions into the Aquality.Selenium nuget package, you can check out our solution - we have cross-browser support with easy json configuration. Template project is located here: https://github.com/aquality-automation/aquality-selenium-dotnet-template