goautomationbrowser-automationheadless-browserchromedp

How to access db while running a webdriver using chromedp?


I want to automate OTP submission on a bank page. I will get the OTP in my database only after webdriver have clicked confirm on the bank page. After confirming, I need to fetch OTP from the db and then automate OTP submission.

  ctx, cancel := chromedp.NewContext(context.Background(),      chromedp.WithDebugf(log.Printf))
    defer cancel()

    // run chromedp tasks
    err := chromedp.Run(ctx,
        chromedp.Navigate(bankUrl),
        chromedp.WaitVisible(`#username`),
        chromedp.SendKeys(`#username`, `usernameXXX`),
        chromedp.WaitVisible(`#label2`, ),
        chromedp.SendKeys(`#label2`, `passwordxxx` ),
        chromedp.Click(`//input[@title="Login"]`),
        chromedp.WaitVisible(`#Go`),
        chromedp.Click(`#Go`),
        chromedp.WaitVisible(`#confirmButton`),
        chromedp.Click(`#confirmButton`),
        chromedp.WaitVisible(`//input[@type="password"]`),
        // perform  fetch OTP below, this raise error
        otp := fetchOTPFromDb()
        chromedp.SendKeys(`//input[@type="password"]`, otp),
        chromedp.WaitVisible(`#confirmButton`),
        chromedp.Click(`#confirmButton`))
    if err != nil {
        log.Fatal(err)
    }

The problem is that chromedp.Run expects all args to be of the type chromedp.Tasks, so I can't call custom functions there and I get error while fetching the OTP from db. How do I go around this?


Solution

  • The solution is to wrap the otp fetch within an Action.Do call, then return the result of a call to chromdp.SendKeys to set the HTML input value.

    It is required to work that way because the One Time Password does not exist until the page was fetched, thus, its read must happen while manipulating the resource.

    Like this

    package main
    
    import "context"
    
    type OTPAction struct {
        // DB ....
    }
    
    func (a OTPAction) Do(ctx context.Context) error {
        // fetch OTP here
        otp := "otp test"
        return chromedp.SendKeys(`//input[@id="user-message"]`, otp).Do(ctx)
    }