Selenium VBA test case as a Function - vba

I am trying do divide my test cases as a function in Selenium VBA using Excel. My first step is to login. I made login as a function for example
Public Sub test()
'my main program is here
'First step login
Login()
End sub
Function Login()
' Open Firefox command
' my commands here
'
End function
what happens is whenever I call Login() and when the function ends, It Closes the browser(in this case Mozilla firefox).

The browser is automatically disposed once the variable of the driver is out of scope. For further information, I invite you to have a look at the official documentation: https://support.microsoft.com/en-gb/kb/141693
Here is an example with a local instance of the driver:
Private Assert As New Assert
Sub Main()
Dim drv As New Selenium.FirefoxDriver
drv.Get "http://stackoverflow.com"
Call ClickLogo(drv)
drv.Quit
End Sub
Sub ClickLogo(drv As WebDriver)
drv.FindElementByCss("#hlogo").Click
End Sub
And another example with a global instance of the driver:
Private Assert As New Assert
Private drv As New Selenium.FirefoxDriver
Sub ProcMain()
drv.Get "http://stackoverflow.com"
Call ClickLogo
drv.Quit
End Sub
Sub ClickLogo()
drv.FindElementByCss("#hlogo").Click
End Sub
To get the latest version in date working with the above examples:
https://github.com/florentbr/SeleniumBasic/releases/latest

Dim your selenium webdriver before the start of your sub, this will allow the webdriver instance to run outside of the 'scope' of your main sub, then use driver.quit to kill the instance at the end of your program

Related

MS Access: instantiating a form within a custom class

I am trying to instantiate an existing form (frmVisibleForm) in my project from within a custom class module (clsMBox) and manipulate its properties from there too. I want to be able to use events from the form.
What I expect to happen:
The Form frmVisibleForm is instantiated but invisible
The Form gets set to Modal
The Form gets set to Visible
The Form gets Focus
What happens:
Nothing. No form shows up, no error messages, no prompts, nothing happens at all when running the test module´s function. Its my first time trying out custom classes in access so maybe I made some fundamental error but I can't figure out why it doesn´t work the way I thought it would. Appreciate any help.
Here is the code I have so far:
The Form (frmVisibleForm):
Option Compare Database
Option Explicit
Public Event DataInput(InputValue As String)
(No actual events thus far)
The Custom Class Module (clsMBox):
Option Compare Database
Option Explicit
Dim WithEvents cls_frmVisibleForm As Form_frmVisibleForm
Private Sub InstantiateForm()
Set cls_frmVisibleForm = New Form_frmVisibleForm
With cls_frmVisibleForm
.Modal = True
.Visible = True
.SetFocus
End With
End Sub
The Module I try to test it from (mdlTestMBox):
Option Compare Database
Option Explicit
Public Function ClassTest()
Dim mbox As clsMBox
Set mbox = New clsMBox
End Function
I guess you need to either make InstantiateForm a public method, and then call that, or rename it to initialise:
Private Sub Class_Initialize()
Static cls_frmVisibleForm As Access.Form
Set cls_frmVisibleForm = New Form_frmVisibleForm
With cls_frmVisibleForm
.Modal = True
.Visible = True
.Move 0, 0
End With
End Sub
To open and close an instance of the form:
Public Function ClassTest()
Static mbox As clsMBox
Set mbox = New clsMBox
Stop
DoCmd.Close acForm, Forms(0).Name
End Function

VBA How To Set Form In Function

I add Form1.vb in my project but ı couldn't show it. Form1.show or Form1.ShowDialog didn't worked beacuse it type is class.
Here is the error message;
bc30109 'form1' is a class type and cannot be used as an expression
Solution must be some think like that.
Private Sub Form1Func()
Dim f1 As Object
f1 = Form1
f1.ShowDialog
End Sub
Private Sub OnButtonClick(cmd As Commands_e)
Select Case cmd
Case Commands_e.Export_As_SheetMetal
Form1Func()
Case Commands_e.AboutUs
Application.ShowMessageBox("AboutUS")
End Select
End Sub
Without knowing more about other actions in your program, I cannot pinpoint why you're being asked to provide an argument for show (possibly a named function, etc.), but this is a way to ensure a form is called as an object:
Dim obj As Object: Set obj = VBA.UserForms.Add("userform1")
obj.Show vbModeless
Specific to your error, the above code directly generates the userform object through vba.
Private Sub Form1Func()
Dim f1 As New Form1
f1.Show()
End Sub

Edge closes automatically at the end of macro

While automating edge browser using selenium vba, the edge browser automatically closes when the macro end sub function is executed. Is there a way to control this action & edge does not close automatically?
So, to avoid quitting the browser, you need to set the instance of the driver on a global variable:
Private Assert As New Assert
Private driver As New Selenium.FirefoxDriver
Sub ProcMain()
driver.Get "http://stackoverflow.com"
Call ClickLogo
End Sub
Sub QuitDriver()
driver.Quit
End Sub
Sub ClickLogo()
driver.FindElementByCss("#hlogo").Click
End Sub
Or For Example for Edge
Dim driver as WebDriver
Sub Repsol()
Set driver = New EdgeDriver
With driver
.Start "edge"
.Get "https://login.repsol.com/es/Landing/AuthnPage?returnUrl=https://www.repsol.com/es_es/"
With .FindElementByClass("gigya-login-form")
.FindElementByClass("gigya-input-text").SendKeys "user" 'your user
.FindElementByClass("gigya-input-password").SendKeys "password" 'your password
.FindElementByClass("gigya-input-submit").submit
End With
Application.Wait Now + TimeSerial(0, 0, 10)
.Get "https://www.repsol.com/es_es/aplicaciones/SO/WebEESS/default.aspx?usuario="""
Application.Wait Now + TimeSerial(0, 0, 10)
.Get "https://www.repsol.com/SO/WebEESS/Pages/Carburantes/PeticionCarburante/Peticion.aspx"
With .FindElementByClass("tablaContenedora")
.FindElementById("ctl00_zona1_grdwCarburantes_ctl02_lbltxtCantidad").SendKeys [B7]
End With
End With
End Sub

Access not firing custom event

I've been building testable MVC logic for my Access database using RubberDuck's answer to Best way to test a MS Access Application? but I'm stuck with the custom event handling. I can't figure out why the OnCreate event isn't firing.
Form_CreateStudents:
Option Compare Database
Private ctrl As ctrCreateStudent
Public Event OnCreate()
Private Sub btnCreate_Click()
Set ctrl = New ctrCreateStudent
ctrl.Run
RaiseEvent OnCreate
End Sub
Class module ctrCreateStudent:
Private WithEvents frm As [Form_Create Students]
Public Sub Run()
MsgBox "run called"
Set frm = New [Form_Create Students]
End Sub
Public Sub frm_OnCreate()
MsgBox "frm_oncreate event called"
End Sub
Run is being called, but frm_OnCreate is just ignored. I'm relatively new to VBA, what am I missing here?
Quite simple:
frm is a New [Form_Create Students], not the one calling it.
This new form doesn't raise the OnCreate event. In fact, this new form is not even visible, because you haven't set frm.Visible = True
If you want to set it to the form that just called Run, pass it:
On the form:
Private ctrl As ctrCreateStudent
Public Event OnCreate()
Private Sub btnCreate_Click()
Set ctrl = New ctrCreateStudent
ctrl.Run Me
RaiseEvent OnCreate
End Sub
On the class:
Private WithEvents frm As [Form_Create Students]
Public Sub Run(parentForm As [Form_Create Students])
MsgBox "run called"
Set frm = parentForm
End Sub
Public Sub frm_OnCreate()
MsgBox "frm_oncreate event called"
End Sub
A strong warning, though: this code contains a reference loop, and thus a memory leak.
The form has a reference to the class, and the class has a reference to the form, so neither will ever get destroyed. Every time you close and open the form, a new form and class object will get created, and none of them will ever get destroyed.
When closing the form, it turns invisible and looks gone, but it's still there and using memory.
There are many ways to work around this, but an easy one is:
In the class:
Public Sub frm_Close()
Set frm = Nothing 'Release form object, break reference loop
End Sub
And make sure the Form's On Close property is set to "[Event Procedure]" so the close event gets raised.

How to schedule an async macro from WORD

I'm facing an annoying issue where I simply want to schedule an asynchronous macro from another instance of Word, which happens to be the same .doc file.
Meaning, in the ThisDocument namespace I have the following code snippet:
Public Sub Document_Open()
Set Obj = New Word.Application
Obj.OnTime Now + TimeValue("00:00:01"), "Module1.Test"
End Sub
I've declared a new object of Word due to the following reasons:
My macro may block user's I\O
The user may close the document before the macro finishes its task
And declared a module named Module1 with a simple MsgBox
Public Sub Test()
MsgBox "hhh"
End Sub
Needless to say, nothing happened, and I'm unable to check what OnTime function returns.
I've also tried the following combinations:
"!Module1.Test"
"c:\\....\\file.doc!Module1.Test"
What am I missing here?
Your newly created Word application, represented by a Word.Application object, doesn't have the document open. Thus there's no "Module1" as far as he's aware. The fact that you want to run code from the same document is immaterial. It's a different instance of Word.
Something like this works:
'''''''' ThisDocument
Option Explicit
Private Sub Document_Open()
Dim res As VbMsgBoxResult
Dim Obj As Word.Application
If Application.Visible Then
res = MsgBox("Hello", vbOKCancel, "Hi!")
Else
Exit Sub
End If
If res = vbOK Then
Set Obj = New Word.Application
Obj.Documents.Open "C:\Users\conio\Desktop\Hello.docm", , True
Obj.OnTime Now + TimeValue("00:00:01"), "Module1.Foo"
End If
End Sub
'''''''' Module1
Public Sub Foo()
If Not Application.Visible Then
MsgBox "Foo"
Application.Quit
End If
End Sub
Maybe you'd want to use a different check to differentiate between the interactive run and the unattended run.