diff --git a/src/webdriver.nim b/src/webdriver.nim index d9d3aba..e345cc9 100644 --- a/src/webdriver.nim +++ b/src/webdriver.nim @@ -9,14 +9,32 @@ type driver: WebDriver id*: string + Element* = object + session: Session + id*: string + + LocationStrategy* = enum + CssSelector, LinkTextSelector, PartialLinkTextSelector, TagNameSelector, + XPathSelector + WebDriverException* = object of Exception ProtocolException* = object of WebDriverException +proc toKeyword(strategy: LocationStrategy): string = + case strategy + of CssSelector: "css selector" + of LinkTextSelector: "link text" + of PartialLinkTextSelector: "partial link text" + of TagNameSelector: "tag name" + of XPathSelector: "xpath" + proc newWebDriver*(url: string = "http://localhost:4444"): WebDriver = WebDriver(url: url.parseUri, client: newHttpClient()) proc createSession*(self: WebDriver): Session = + ## Creates a new browsing session. + # Check the readiness of the Web Driver. let resp = self.client.getContent($(self.url / "status")) let obj = parseJson(resp) @@ -39,6 +57,7 @@ proc createSession*(self: WebDriver): Session = return Session(id: sessionObj["value"]["sessionId"].getStr(), driver: self) proc navigate*(self: Session, url: string) = + ## Instructs the session to navigate to the specified URL. let reqUrl = $(self.driver.url / "session" / self.id / "url") let obj = %*{"url": url} let resp = self.driver.client.postContent(reqUrl, $obj) @@ -48,6 +67,7 @@ proc navigate*(self: Session, url: string) = raise newException(WebDriverException, $respObj) proc getPageSource*(self: Session): string = + ## Retrieves the specified session's page source. let reqUrl = $(self.driver.url / "session" / self.id / "source") let resp = self.driver.client.getContent(reqUrl) @@ -57,9 +77,34 @@ proc getPageSource*(self: Session): string = return respObj{"value"}.getStr() +proc findElement*(self: Session, selector: string, + strategy = CssSelector): Element = + let reqUrl = $(self.driver.url / "session" / self.id / "element") + let reqObj = %*{"using": toKeyword(strategy), "value": selector} + let resp = self.driver.client.postContent(reqUrl, $reqObj) + + let respObj = parseJson(resp) + if respObj{"value"}.isNil: + raise newException(WebDriverException, $respObj) + + for key, value in respObj["value"].getFields().pairs(): + return Element(id: value.getStr(), session: self) + +proc getText*(self: Element): string = + let reqUrl = $(self.session.driver.url / "session" / self.session.id / + "element" / self.id / "text") + let resp = self.session.driver.client.getContent(reqUrl) + let respObj = parseJson(resp) + if respObj{"value"}.isNil: + raise newException(WebDriverException, $respObj) + + return respObj["value"].getStr() + when isMainModule: let webDriver = newWebDriver() let session = webDriver.createSession() - echo(session) - session.navigate("https://picheta.me") - echo(session.getPageSource()) + let amazonUrl = "https://www.amazon.co.uk/Nintendo-Classic-Mini-" & + "Entertainment-System/dp/B073BVHY3F" + session.navigate(amazonUrl) + + echo session.findElement("#priceblock_ourprice").getText() \ No newline at end of file