Search code examples
windowspowershellseleniumfirefoxautomation

Firefox automation using Selenium Powershell ISE, Windows 10


PS ISE 5.1 Windows 10

Has anyone had luck with Firefox automation using Selenium with PS ISE? Below, I have two different examples below where in each method I am unsuccessfully able to open the firefox browser, let alone navigate anywhere. I'll explain more under each method.

Method 1) Install of Selenium PS Module: Source: https://github.com/adamdriscoll/selenium-powershell

In the following method, I installed a module that is supposed to be a powershell wrapper for C# Selenium. The error is triggered from module itself. I have placed the error message in the comment block below. How would I find which "assembly" is needed, that contains this "type"?


    cls
    $website = "https://www.google.com/"
    Import-Module "C:\Program Files\WindowsPowerShell\Modules\Selenium\3.0.1\Selenium.psm1" -Function *
    $Driver = Start-SeFirefox
    Enter-SeUrl $website -Driver $Driver
    
Cannot find the type for custom attribute 'ValidateURIAttribute'. Make sure that the assembly that contains this type is loaded.
At C:\Program Files\WindowsPowerShell\Modules\Selenium\3.0.1\Selenium.psm1:403

char:9 + [ValidateURIAttribute()] + ~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: ([ValidateURIAttribute()]:AttributeAst) [], RuntimeException + FullyQualifiedErrorId : CustomAttributeTypeNotFound Cannot find the type for custom attribute 'ValidateURIAttribute'. Make sure that the assembly that contains this type is loaded. At C:\Program Files\WindowsPowerShell\Modules\Selenium\3.0.1\Selenium.psm1:580 char:9 + [ValidateURIAttribute()] + ~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: ([ValidateURIAttribute()]:AttributeAst) [], RuntimeException + FullyQualifiedErrorId : CustomAttributeTypeNotFound

Method 2) Downloaded geckodriver.exe and WebDriver.dll Sources:

https://www.reddit.com/.../getting_started_in_web.../

https://adamtheautomator.com/selenium-powershell/

https://www.selenium.dev/downloads/

In this example, I have downloaded geckodriver.exe and WebDriver.dll, placed them both in the same folder and added the folder to my system's environment variables. I've added a comment block below showing the error message. I commented out the Add-type call as it gave me different errors and it didn't load the webdriver, so I used the loadform call instead. Which file is the error referencing to? The code is using the DLL file; I know this because FireFoxOptions line of code works and the code opens the exe, so that clearly is found as well. There are only 2 files and both are working to some degree. The line that's not working is


    $Firefoxdriver = New-Object OpenQA.Selenium.Firefox.Firefoxdriver($Firefoxoptions)

This would be a function from the dll file; can it not find the EXE at this point, even though the code had already executed the EXE file? Regarding the GAC = false, I read that not all DLL's can be registered with the system because some don't have all the necessary functions; I'm not sure if that's required or not.


    cls
    $PathToFolder = 'F:\Programs\Selenium\WorkingDirectory'
    if ($env:Path -notcontains ";$PathToFolder" ) {
        $env:Path += ";$PathToFolder"
    }
    [System.Reflection.Assembly]::LoadFrom("{0}\\WebDriver.dll" -f $PathToFolder)
    #Add-Type -Path "$($PathToFolder)\WebDriver.dll"
    $Firefoxoptions = New-Object OpenQA.Selenium.Firefox.Firefoxoptions
    #$Firefoxoptions.AddArgument('-headless') ##### <----- Used to make the window not appear, or 'headless' - comment out to have a normal window show.
    $Firefoxoptions.AcceptInsecureCertificates = $True
    $Firefoxdriver = New-Object OpenQA.Selenium.Firefox.Firefoxdriver($Firefoxoptions)
    pause
GAC    Version        Location                                                                                                                                                
---    -------        --------                                                                                                                                                
False  v4.0.30319     F:\Programs\Selenium\WorkingDirectory\WebDriver.dll                   


New-Object : Exception calling ".ctor" with "1" argument(s): "Could not load file or assembly 'Newtonsoft.Json, Version=10.0.0.0,

Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The system cannot find the file specified." At F:\Programs\PowerShell\SeleniumFireFox.ps1:15 char:18 + ... foxdriver = New-Object OpenQA.Selenium.Firefox.Firefoxdriver($Firefox ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: 🙂) [New-Object], MethodInvocationException + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand Press Enter to continue...:

Here is a snippet of the Java code that works in Eclipse. I wonder if what I'm missing in the code above is whatever the System.setProperty is doing in Java?

    public static void main(String[] args) {
     System.setProperty("webdriver.gecko.driver","F:\\Programs\\Selenium\\GeckoDriver\\geckodriver-v0.29.0-win64\\geckodriver.exe");
     WebDriver driver = new FirefoxDriver();
     String baseUrl = "https://www.google.com/";
             String expectedTitle = "Google";
             String actualTitle = "";
             // launch Fire fox and direct it to the Base URL
             driver.get(baseUrl);

Additional notes (partly just venting): The reason I'm trying to do this in powershell is because I know powershell more; it's generally easier for me to write code. In my example, I am trying to combine two pieces of working code together; one of them is the Firefox automation in Java and the other is an api call in Powershell. My first attempt was to port the powershell code into Java, but I don't know Java well and the littlest things were frustrating me. In Java, I couldn't figure out how to make the API call which was so simple in powershell; simply using Invoke-RestMethod. The answers I found online to do that were saying that it's actually complex in Java because I would need to manage cookies and do all sorts of stuff. I couldn't even find consistent date functions; different answers were importing different date function modules and it made combining code difficult. So, I decided to try and port my Java code to Powershell. The code I'm using works for other people, at least according to the answers I've found online, but do not work for me.


Solution

  • It looks like you are not importing the full module, is this on purpose? If Selenium is in your modules path, you should be able to run:

    Import-Module Selenium
    

    If that's not possible, most modules have a .psd1 file that should be the import target, and may load other .psm1 files, nested modules, assemblies, etc. Your github link recommends the following:

    Import-Module "{FullPath}\selenium-powershell\Selenium.psd1"
    

    At the very least, you are missing a type definition - these are usually included in .dll or .xml files with the module, and can be seen with get-module once imported under ExportedTypeFiles:

    (Get-Module ActiveDirectory).ExportedTypeFiles
    C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\ActiveDirectory\ActiveDirectory.Types.ps1xml