Search code examples
windowsgoogle-chromefirefoxprintingautoit

How to handle print- and "Save Print output as" browser windows?


  1. I have to visit an URL, login using credentials, then select a region name and click on show button so that a recent bill in the HTML page is shown (all this I did using a Selenium script).

  2. There is a button Print Option on that page. When clicked the print popup appears and I need to click OK. But I am not able to do so using an AutoIt script either.

    enter image description here

  3. When a click on OK is done the "Save Print Output As" window opens where I have to enter the file name and click Save.

    enter image description here

These two pop-up windows differ for Firefox and Chrome. How to handle these? I tried using an AutoIt script and by calling it using Runtime .exec(file name) in a Selenium script, but neither works for me.

WinWait("Print", "", 5000)

If WinExists("Print", "") Then
    Send("OK{ENTER}")
EndIf

Sleep(5000)
WinWait("Save Print Output As", "", 5000)

If WinExists("Save Print Output As", "") Then
    ControlFocus("Save Print Output As", "", "Edit1")
    Sleep(5000)
    ControlSetText("Save Print Output As", "", "Edit1", "H282")
    Sleep(5000)
    ControlClick("Save Print Output As", "", "Button2")
EndIf

Also I need to run the script many times for different regions, but it stops execution after first run.

The Window Info Tool Summary for 'Print' and 'Save as Print Output' pop-up are-

AutoIt Window Info of Print pop-up

AutoIt Window Info of 'Save as Print Output' for the Field to Enter File Name

AutoIt Window Info of 'Save as Print Output' for the Save Field

Issue is- selenium code is executed well and when print option is clicked then to handle print window, using .exe file is called and it starts to run in background. but doesn't work. The execution stops once the print window is opened.

Now the New pop-up is seen , when file name is entered in 'Edit1" for each different file name

New Offset window is shown


Solution

  • Opt("TrayIconDebug", True)
    
    ; String in filename to replace with an incremented integer.
    $sTag = "++1"
    
    ; Show custom progress window (True|False).
    $bEnableProgress = True
    
    Switch $CMDLINE[0]
        Case 0
            Exit
    
        Case 1
            If $CMDLINE[1] = '/?' Then
                ; Help message.
                _HelpMsg()
                Exit
            Else
                ; Assign default command line array.
                $aFilenames = $CMDLINE
            EndIf
    
        Case 2
            ; If not $sTag in the 1st argument, then goto the next case.
            If Not StringInStr($CMDLINE[1], $sTag) Then ContinueCase
    
            ; If the 2nd argument is not an integer, then goto the next case.
            If Not StringIsInt($CMDLINE[2]) Then ContinueCase
    
            ; Create array with filenames starting from index 1.
            Global $aFilenames[$CMDLINE[2] + 1]
    
            $aFilenames[0] = Int($CMDLINE[2])
    
            ; Find first filepath that does not exist and set an offset.
            $iOffset = 0
    
            For $i1 = 1 To 1000
                If Not FileExists(StringReplace($CMDLINE[1], $sTag, $i1, -1)) Then
                    $iOffset = $i1 - 1
                    ExitLoop
                EndIf
            Next
    
            ; Assign the array with filenames, replacing tag with an integer.
            For $i1 = 1 To $aFilenames[0]
                $aFilenames[$i1] = StringReplace($CMDLINE[1], $sTag, $i1 + $iOffset, -1)
            Next
    
        Case Else
            ; Assign default command line array.
            $aFilenames = $CMDLINE
    EndSwitch
    
    If $bEnableProgress Then
        ProgressOn(@ScriptName, 'SaveAs')
    EndIf
    
    For $i1 = 1 To $aFilenames[0]
        ; Filename to save as.
        $sSaveAsFilename = $aFilenames[$i1]
    
        ; Print window.
        $hPrint = WinWait("Print")
        ControlClick($hPrint, "", "OK")
    
        ; Progress window.
        $hProgress = WinWait("Printing")
    
        ; Save As window.
        $hSaveAs = WinWait("Save Print Output As")
    
        Do
            Sleep(500)
            ControlSetText($hSaveAs, "", "Edit1", $sSaveAsFilename)
        Until ControlGetText($hSaveAs, "", "Edit1") = $sSaveAsFilename
    
        Sleep(500)
    
        If $bEnableProgress Then
            ProgressSet(100 / $aFilenames[0] * $i1, $sSaveAsFilename)
        EndIf
    
        ControlClick($hSaveAs, "", "Button2")
        AdlibRegister("_ConfirmSaveAs")
        WinWaitClose($hSaveAs)
        AdlibUnRegister("_ConfirmSaveAs")
    
        ; Wait for the progress window to close.
        WinWaitClose($hProgress)
    Next
    
    If $bEnableProgress Then ProgressOff()
    
    Exit
    
    Func _ConfirmSaveAs()
        ; Handle possible msgbox to confirm overwrite.
        If WinExists("Confirm Save As") Then
            ControlClick("Confirm Save As", "", "&Yes")
        EndIf
    EndFunc
    
    Func _HelpMsg()
        ; Help message.
        MsgBox(0, @ScriptName, _
         "Automates the standard print dialog from a web browser." & @CRLF & _
         @CRLF & _
         "Syntax:" & @CRLF & _
         "  " & @ScriptName & " filepath [filepath] ..." & @CRLF & _
         "  " & @ScriptName & " filepath integer" & @CRLF & _
         @CRLF & _
         "1st syntax can pass 1 or more filepath arguments." & @CRLF & _
         @CRLF & _
         "2nd syntax replaces the tag " & $sTag & " from right side of the " & _
         "1st argument with an incremented integer (starting from 1). " & _
         "Example: test" & $sTag & ".pdf will start with test1.pdf and end " & _
         "with testN.pdf (which N is the integer set by the 2nd argument)." & @CRLF & _
         @CRLF & _
         "Tested with Firefox 63 on Windows 10.")
    EndFunc
    

    The filename|filepath can be passed as arguments. If you want to save as 1 filename then use:

    scriptname.exe "C:\SaveFolder\a.pdf"
    

    You can also do many in same execution i.e.:

    scriptname.exe "C:\SaveFolder\a.pdf" "C:\SaveFolder\b.pdf" ...
    

    If you want to increment the filenames with an integer, then i.e.:

    scriptname.exe "C:\SaveFolder\a++1.pdf" 3
    

    which ++1 will be replaced with an integer and will be processed as if it were:

    scriptname.exe "C:\SaveFolder\a1.pdf" "C:\SaveFolder\a2.pdf" "C:\SaveFolder\a3.pdf"
    

    The 1st argument must contain string ++1 and the 2nd argument must be an integer to be recognized as a base filename to be incremented.

    Help Msgbox can be shown by using the /? as the only argument.

    Many arguments in same execution may not be suitable for control in your Selenium script though it is an option.

    These windows are standard print dialogs so difference between Chrome and Firefox may be none. The "Printing" window is not the same if you print from i.e. Notepad so that window cannot be considered standard.

    Set $sSaveAsFilename to the value that will be set into the edit control of "File name:", in the window titled "Save Print Output As".

    Opt parameter of TrayIconDebug will display the current line in the system tray while the mouse cursor hovers over the icon. So if it stalls, then you can trace if it gets trapped. This is an optional function call.

    This was tested in a Windows 10 Virtual Machine using Firefox 63. The windows appear slow on display which is why Edit1 is checked for the correct string before continuing. An alternative is to use Opt() and parameter WinWaitDelay at approximately 1000 to pause after a window shows, though the script may take longer to complete on average.

    I added an AdlibRegister function for repetitive testing and may still be useful as a file name may unknowingly exist which needs to be handled.

    The "Printing" window is waited for primarily, just to stop the script from closing before the printing progress is done. If unwanted, then remove the relevant code.