Niminem / ChromeDevToolsProtocol

Low-level Nim wrapper for Chrome DevTools Protocol (CDP). Bend Chrome to your will with complete control over your browser. Scrape dynamic webpages, create browser automations, and beyond. Wield responsibly ;)
https://niminem.github.io/CDP/cdp.html
MIT License
34 stars 2 forks source link

question: how to get session id via target id #2

Open bung87 opened 5 months ago

bung87 commented 5 months ago

I wanna inject script into tabs, whether it's opened by program or user, so I am able to get list of tabs via getTargets, tried attachToTarget it returns a different session id from the id created via newTab

when I tried to call cdp command it give {"code":-32001,"message":"Session with given id not found."}

btw, it's also related to another problem, it opened a tab after launch, I am not able retrive the tab

Niminem commented 5 months ago

@bung87

For your first point, can you give me a small example of how you're trying to achieve this?

For your second point, there is a default tab that's opened after launch and has different properties that the others (a browser context). Check out the Protocol Fundamentals section in this readme: https://github.com/aslushnikov/getting-started-with-cdp/

It's worth reading that because he also explains Target.setDiscoverTargets and other concepts I might have done a terrible job explaining in comparison.

Happy to help work through this with you, that's something I'll need to do in the near future as well.

bung87 commented 5 months ago

example for second one, same theory as first one.

proc getTabs(browser: Browser;): Future[seq[string] ] {.async} = 
  let resp = await session.getTargets(%* {"filter": [{"type": "tab", "exclude": false}]})
  if "result" in resp:
    let targetinfos = resp["result"]["targetInfos"].to(seq[TargetInfo])
    for info in targetinfos:
      if info.url.startsWith("http") or info.url == "chrome://newtab/":
        result.add info.targetId

proc sendCommand*(browser: Browser; sessionId: string; mthd: string; params: JsonNode): Future[JsonNode] {.async.} =
  ## Version of `sendCommand` that sends a command with parameters (for the Tab object).
  browser.requestId += 1
  if browser.requestId > 9999: browser.requestId = 1
  let msg = %*{"id": browser.requestId, "method": mthd,
                "sessionId": sessionId, "params": params}
  let future = newFuture[JsonNode]()
  browser.responseTable[browser.requestId] = future
  await browser.ws.send($msg)
  result = await future

proc main(){.async.} =
  let session = await launchBrowser(headlessMode = HeadlessMode.Off,chromeArguments = chromeArgs) # launch a new browser
  await session.setDiscoverTargets(true)

  await session.setAutoAttach(true, false)
  let tabs = await session.getTabs()
  let resp = await session.attachToTarget(tabs[0])

  let sessionId = resp["result"]["sessionId"].getStr
  const Entry = "https://nim-lang.org"

  discard await session.sendCommand("Page.navigate",sessionId, %*{"url": Entry})
Niminem commented 5 months ago

@bung87 Thank you will look into this today Bung

bung87 commented 5 months ago

it's same steps as https://github.com/aslushnikov/getting-started-with-cdp/?tab=readme-ov-file#targets--sessions

my app also has button let user manually inject script , so after launch I click it, found the tab "chrome://newtab/" attached property become true when I check getTabs result.

bung87 commented 4 months ago

any news?

Niminem commented 4 months ago

@bung87 I think what we need to do is have another property for the Browser object called tabs that will hold ALL Tab objects, including the default tab that's opened up when Chrome opens. It seems this is also what Puppeteer is doing:

https://pptr.dev/api/puppeteer.browser

We can have it setup where, for example, any new tab that gets created is accessible from the Browser object as well.

Niminem commented 4 months ago

So.. when the browser is opened, it automatically searches for available page targets (the default one) and immediately attaches to it, creating a Tab object with the appropriate sessionId.

This should resolve your problem... I think!

Niminem commented 4 months ago

I will be taking a look at this over the weekend and try to get this squared away and tested.

Niminem commented 4 months ago

It's going to take a little time before I'm able to dive into this and expand the library further. I'm aiming for this week but it may be a little longer.

bung87 commented 4 months ago

any update?

Niminem commented 3 months ago

@bung87 Not yet unfortunately, work has got extremely busy and this will require an expansion/extension to the library (more similar to the Puppeteer API). Leaving this ticket open and will get to it when I'm able to breathe.

bung87 commented 3 months ago

it seems related to this https://phabricator.services.mozilla.com/D151843, I tried again, I was able to retrieve the first tab, but it response <xxx cdp command> wasn't found every time I run cdp command, so it's not usefull .

Niminem commented 1 month ago

@bung87 I will have quite some time on my hands in the coming weeks and plan on updating the API to be a little more like Puppeteer, and explore how they're managing tabs. I've been using this library and so far haven't ran into these issues... then again my use case has been much simpler.