Skip to content

Commit

Permalink
add documentation/licensing
Browse files Browse the repository at this point in the history
  • Loading branch information
wirepair committed Nov 4, 2015
1 parent 559ebad commit aaba77c
Show file tree
Hide file tree
Showing 11 changed files with 258 additions and 32 deletions.
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ autogcd requires [gcd](https://github.com/wirepair/gcd/), [gcdapi](https://githu

## The API
Autogcd is comprised of four components:
* autogcd - The wrapper around gcd.Gcd.
* settings - For managing startup of autogcd.
* AutoGcd - The wrapper around gcd.Gcd.
* Settings - For managing startup of autogcd.
* Tab - Individual chrome tabs
* Element - Elements that make up the Page

Expand All @@ -23,7 +23,7 @@ The chrome debugger service uses internal nodeIds for identifying unique element


### Frames
If you need to search elements (by id or by a selector) of a frame's #document, you'll need to get an Element reference that is the iframe's #document. This can be done by doing a tab.GetElementsBySelector("iframe"), iterating over them and calling element.GetFrameDocumentNodeId(). This will return the internal document node id which you can then pass to tab.GetDocumentElementsBySelector(iframeDocNodeId, "#whatever").
If you need to search elements (by id or by a selector) of a frame's #document, you'll need to get an Element reference that is the iframe's #document. This can be done by doing a tab.GetElementsBySelector("iframe"), iterating over the results and calling element.GetFrameDocumentNodeId(). This will return the internal document node id which you can then pass to tab.GetDocumentElementsBySelector(iframeDocNodeId, "#whatever").

### Windows
The major limitation of using the Google Chrome Remote Debugger is when working with windows. Since each tab must have the debugger enabled, calls to window.open will open a new window prior to us being able to attach a debugger. To get around this, you'll need to get a list of tabs AutoGcd.GetAllTabs(), then call AutoGcd.RefreshTabList() which will connect each tab to an autogcd.Tab. You'd then need to reload the tab get begin working with it.
Expand All @@ -33,7 +33,12 @@ There are a few ways you can test for stability or if an Element is ready. Eleme

Finally, you can use the tab.WaitFor method, which takes a ConditionalFunc type and repeatedly calls it until it returns true, or times out.

For example/simple ConditionalFuncs see the [conditionals.go](https://github.com/wirepair/autogcd/tree/master/conditionals.go) source. Of course you can use whatever you want as long as it matches the ConditionalFunc prototype.
For example/simple ConditionalFuncs see the [conditionals.go](https://github.com/wirepair/autogcd/tree/master/conditionals.go) source. Of course you can use whatever you want as long as it matches the ConditionalFunc signature.

### Navigation Errors
Unlike webdriver, we can actually determine if navigation fails. After tab.Navigate(url), calling tab.DidNavigationFail() will return a true/false return value along with a string of the failure type if one did occur.

### SSL Errors


### Input
Expand All @@ -46,7 +51,7 @@ Four listener functions have been implemented, GetConsoleMessages, GetNetworkTra
Pass in a ConsoleMessageFunc handler to begin receiving console messages from the tab. Use StopConsoleMessages to stop receiving them.

#### GetNetworkTraffic
Pass in either a NetworkRequestHandlerFunc, NetworkResponseHandlerFunc or NetworkFinishedHandlerFunc handler (or all three) to receive network traffic events. NetworkFinishedHandler's should be used to signal your application that it's safe to get the response body of the request. While calling GetResponseBody *may* work from NetworkResponseHandlerFunc, it will in many cases fail as the debugger service isn't ready to return the data yet. Use StopNetworkTraffic to stop receiving them.
Pass in either a NetworkRequestHandlerFunc, NetworkResponseHandlerFunc or NetworkFinishedHandlerFunc handler (or all three) to receive network traffic events. NetworkFinishedHandler should be used to signal your application that it's safe to get the response body of the request. While calling GetResponseBody *may* work from NetworkResponseHandlerFunc, it will in many cases fail as the debugger service isn't ready to return the data yet. Use StopNetworkTraffic to stop receiving them.

#### GetStorageEvents
Pass in a StorageFunc handler to recieve cleared, removed, added and updated storage events. Use StopStorageEvents to stop receiving them.
Expand Down
26 changes: 25 additions & 1 deletion api_overrides.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
/*
The MIT License (MIT)
Copyright (c) 2015 isaac dawson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

package autogcd

import (
Expand All @@ -14,7 +38,7 @@ work.

// Evaluate - Evaluates expression on global object.
// This method is overriden because the docs lie, passing 0 returns invalid context id, we must remove it from the map
// entirely for the call go work on the global object.
// entirely for the call to work on the global object.
// expression - Expression to evaluate.
// objectGroup - Symbolic group name that can be used to release multiple objects.
// includeCommandLineAPI - Determines whether Command Line API should be available during the evaluation.
Expand Down
28 changes: 26 additions & 2 deletions autogcd.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
/*
The MIT License (MIT)
Copyright (c) 2015 isaac dawson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/*
Autogcd - An automation interface for https://github.com/wirepair/gcd. Contains most functionality
found in WebDriver and extends it to offer more low level features. This library was built due to
Expand All @@ -11,8 +35,8 @@ is in a Ready state. If an Element is Invalid, it should no longer be used and r
discarded.
Dealing with frames is also different than WebDriver. There is no SwitchToFrame, you simply pass in the frameId
to certain methods that require it. Internally a list of Documents is stored and will look up the element provided
a valid frameId is supplied.
to certain methods that require it. You can lookup the these frame documents by finding frame/iframe Elements and
requesting the document NodeId reference via the GetFrameDocumentNodeId method.
Lastly, dealing with windows... doesn't really work since they open a new tab. A possible solution would be to monitor
the list of tabs by calling AutoGcd.RefreshTabs() and doing a diff of known versus new. You could then do a Tab.Reload()
Expand Down
17 changes: 10 additions & 7 deletions autogcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,17 @@ var (
var testStartupFlags = []string{"--test-type", "--ignore-certificate-errors", "--allow-running-insecure-content", "--disable-new-tab-first-run", "--no-first-run", "--disable-translate", "--safebrowsing-disable-auto-update", "--disable-component-update", "--safebrowsing-disable-download-protection"}

func init() {
defaultChrome := "/usr/lib/chromium-browser/chromium-browser"
defaultDir := "/tmp"
if runtime.GOOS == "windows" {
defaultChrome = "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe"
defaultDir = "C:\\temp\\"
switch runtime.GOOS {
case "windows":
flag.StringVar(&testPath, "chrome", "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe", "path to chrome")
flag.StringVar(&testDir, "dir", "C:\\temp\\", "user directory")
case "darwin":
flag.StringVar(&testPath, "chrome", "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", "path to chrome")
flag.StringVar(&testDir, "dir", "/tmp/", "user directory")
case "linux":
flag.StringVar(&testPath, "chrome", "/usr/bin/chromium-browser", "path to chrome")
flag.StringVar(&testDir, "dir", "/tmp/", "user directory")
}
flag.StringVar(&testPath, "chrome", defaultChrome, "path to chrome/chromium")
flag.StringVar(&testDir, "dir", defaultDir, "user directory")
flag.StringVar(&testPort, "port", "9222", "Debugger port")
}

Expand Down
24 changes: 24 additions & 0 deletions conditionals.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
/*
The MIT License (MIT)
Copyright (c) 2015 isaac dawson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

package autogcd

import (
Expand Down
27 changes: 27 additions & 0 deletions element.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
/*
The MIT License (MIT)
Copyright (c) 2015 isaac dawson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

package autogcd

import (
Expand Down Expand Up @@ -280,6 +304,7 @@ func (e *Element) updateChildNodeCount(newValue int) {
e.node.ChildNodeCount = newValue
}

// adds the child to our DOMNode.
func (e *Element) addChild(child *gcdapi.DOMNode) {
e.lock.Lock()
if e.node.Children == nil {
Expand All @@ -290,12 +315,14 @@ func (e *Element) addChild(child *gcdapi.DOMNode) {
e.lock.Unlock()
}

// adds the children to our DOMNode
func (e *Element) addChildren(childNodes []*gcdapi.DOMNode) {
for _, child := range childNodes {
e.addChild(child)
}
}

// removes the child from our DOMNode
func (e *Element) removeChild(removedNode *gcdapi.DOMNode) {
var idx int
var child *gcdapi.DOMNode
Expand Down
15 changes: 13 additions & 2 deletions examples/googler/googler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/wirepair/autogcd"
"io/ioutil"
"log"
"runtime"
"time"
)

Expand All @@ -26,8 +27,17 @@ var stableAfter = time.Millisecond * 450
var stabilityTimeout = time.Second * 2

func init() {
flag.StringVar(&chromePath, "chrome", "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe", "path to Xvfb")
flag.StringVar(&userDir, "dir", "C:\\temp\\", "user directory")
switch runtime.GOOS {
case "windows":
flag.StringVar(&chromePath, "chrome", "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe", "path to chrome")
flag.StringVar(&userDir, "dir", "C:\\temp\\", "user directory")
case "darwin":
flag.StringVar(&chromePath, "chrome", "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", "path to chrome")
flag.StringVar(&userDir, "dir", "/tmp/", "user directory")
case "linux":
flag.StringVar(&chromePath, "chrome", "/usr/bin/chromium-browser", "path to chrome")
flag.StringVar(&userDir, "dir", "/tmp/", "user directory")
}
flag.StringVar(&chromePort, "port", "9222", "Debugger port")
flag.BoolVar(&debug, "debug", false, "Show debug DOM node event changes")
}
Expand Down Expand Up @@ -69,6 +79,7 @@ func main() {
if err != nil {
log.Fatalf("error sending keys to element: %s\n", err)
}

err = tab.WaitFor(waitForRate, waitForTimeout, autogcd.TitleContains(tab, "github gcd"))
if err != nil {
log.Println("timed out waiting for title to change to github gcd")
Expand Down
29 changes: 28 additions & 1 deletion settings.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
/*
The MIT License (MIT)
Copyright (c) 2015 isaac dawson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

package autogcd

import (
Expand Down Expand Up @@ -28,14 +52,17 @@ func NewSettings(chromePath, userDir string) *Settings {
return s
}

// Can really only be localhost, but this may change in the future so support it anyways.
func (s *Settings) SetChromeHost(host string) {
s.chromeHost = host
}

// Sets the chrome debugger port.
func (s *Settings) SetDebuggerPort(chromePort string) {
s.chromePort = chromePort
}

// How long to wait for chrome to startup and allow us to connect.
func (s *Settings) SetStartTimeout(timeout time.Duration) {
s.timeout = timeout
}
Expand All @@ -51,7 +78,7 @@ func (s *Settings) AddStartupFlags(flags []string) {
}

// Adds a custom extension to launch with chrome. Note this extension MAY NOT USE
// the chrome.debugger API since you can not attach to a Tab twice with debuggers.
// the chrome.debugger API since you can not attach debuggers to a Tab twice.
func (s *Settings) AddExtension(paths []string) {
for _, ext := range paths {
s.extensions = append(s.extensions, fmt.Sprintf("--load-extension=%s", ext))
Expand Down
Loading

0 comments on commit aaba77c

Please sign in to comment.