secret-agent icon indicating copy to clipboard operation
secret-agent copied to clipboard

example for waiting for a form submit

Open tcurdt opened this issue 2 years ago • 8 comments

I was just trying to submit a form - but I haven't found any docs (missed?) or examples that wait for form submit. What's the correct way to wait for the page to have loaded in this case?

const agent = require('secret-agent');

(async () => {
  await agent.configure({ userAgent: '~ chrome = 88' });

  await agent.goto('https://www.duckduckgo.com/')
  await agent.waitForPaintingStable()
  console.log(await agent.url);

  await agent.click(agent.document.querySelector('#search_form_input_homepage'))
  await agent.type('foo')

  await agent.click(agent.document.querySelector('#search_button_homepage'))
  // await agent.waitForLocation('change')
  // await agent.waitForPaintingStable()
  await agent.waitForMillis(3000)

  await agent.close()
})()

tcurdt avatar Feb 12 '22 15:02 tcurdt

Hi @tcurdt, that's a good idea for an example. Your commented out lines seem to be correct. Were they not doing what you expected?

blakebyrnes avatar Feb 15 '22 21:02 blakebyrnes

Sometimes paintingStable is what you want, other times you have a specific element (or many) you're waiting for. waitForElement would be appropriate in that latter case.

blakebyrnes avatar Feb 15 '22 21:02 blakebyrnes

I just wanted to double check but now I've run into some sessions trouble. Still a bit unclear how to configure the path.

const agent = require('secret-agent');

//SA_SESSIONS_DIR=/your-absolute-dir-path

(async () => {
  await agent.configure({
    userAgent: '~ chrome = 88',
    // sessionsDir: '.sessionsX',
  })

  await agent.goto('https://www.duckduckgo.com/')
  await agent.waitForPaintingStable()
  console.log(await agent.url)

  await agent.click(agent.document.querySelector('#search_form_input_homepage'))
  await agent.type('foo fighters')

  await agent.click(agent.document.querySelector('#search_button_homepage'))
  await agent.waitForLocation('change')

  const results = agent.document.querySelector('.results')
  await agent.waitForElement(results)
  await agent.waitForPaintingStable()
  // await agent.waitForMillis(3000)

  console.log(results)

  await agent.close()
})()

It seems like the waitForElement returns too early and the whole script just stops before the page is finished.

I am also a little unsure whether I should use agent or the active tab.

Another thing that I am wondering: for a form submit - I need to click the button? or is there a way to really submit the/a form?

tcurdt avatar Feb 15 '22 21:02 tcurdt

 const results = agent.document.querySelector('.results')
 await agent.waitForElement(results)

Is it possible that .results is on the page but not visible yet? You can pass in an option of waitForVisible if you're wanting it to be on the page, not just "existing". It's also usually good to double check that there's only a single result for that querySelector. That's an easy one to get tripped up on

I am also a little unsure whether I should use agent or the active tab.

agent is just a shortcut to your active tab. Same functionality.

Another thing that I am wondering: for a form submit - I need to click the button? or is there a way to really submit the/a form?

It's going to be anything a user could do - hit entry, click the button, etc

blakebyrnes avatar Feb 15 '22 22:02 blakebyrnes

I got much further - but things are still a bit weird. Here is the full code:

const { Agent } = require('secret-agent');

(async () => {

  const agent = await new Agent({
    userAgent: '~ chrome = 88',
    viewport: {
      screenHeight: 1024,
      screenWidth: 768,
      height: 1024,
      width: 768,
    }
  })

  await agent.goto('https://www.duckduckgo.com/')
  await agent.waitForPaintingStable()
  console.log(await agent.url)

  await agent.click(agent.document.querySelector('#search_form_input_homepage'))
  await agent.type('torsten curdt')

  await agent.click(agent.document.querySelector('#search_button_homepage'))
  await agent.waitForLocation('change')

  const results = agent.document.querySelector('.results')
  await agent.waitForElement(results, { waitForVisible: true })
  await agent.waitForPaintingStable()

  await agent.click(agent.document.querySelector('a.result--more__btn'))
  await agent.waitForPaintingStable()

  for (const link of await results.querySelectorAll('a.result__url')) {
    agent.output.push({
      href: await link.href,
    })
  }

  await agent.close()

})()

The output of the results seems correct - but the browser on the left seems empty.

tcurdt avatar Feb 15 '22 23:02 tcurdt

By "Browser", do you mean the Replay UI? If so, you might have hit a bug in the reproduction of the page. You can tell by looking in the devtools console - it will tell you if you're looking at Replay. I'll see if I can reproduce in interim. Thanks for the snippet!

blakebyrnes avatar Feb 16 '22 14:02 blakebyrnes

By "Browser", do you mean the Replay UI?

I've attached a screenshot. The devtools look OKish.

Screenshot 2022-02-16 at 15 27 15

tcurdt avatar Feb 16 '22 14:02 tcurdt

I just tried myself. There's a bug reproducing the page. If you want to see the real browser (before I fix this), you can set an env var SA_SHOW_BROWSER=1. (or in code, process.env.SA_SHOW_BROWSER='1');

blakebyrnes avatar Feb 16 '22 14:02 blakebyrnes