diff --git a/autogcd.go b/autogcd.go index 0da0b5b..9a426dc 100644 --- a/autogcd.go +++ b/autogcd.go @@ -13,11 +13,18 @@ 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. + +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() +to refresh the page. It is recommended that you clear cache on the tab first so it is possible to trap the various +network events. There are other dirty hacks you could do as well, such as injecting script to override window.open, +or rewriting links etc. */ package autogcd import ( "github.com/wirepair/gcd" + "os" "sync" ) @@ -52,15 +59,11 @@ func NewAutoGcd(settings *Settings) *AutoGcd { // Starts Google Chrome with debugging enabled. func (auto *AutoGcd) Start() error { - var tabs []*gcd.ChromeTarget - var err error auto.debugger.StartProcess(auto.settings.chromePath, auto.settings.userDir, auto.settings.chromePort) - - tabs, err = auto.debugger.GetTargets() + tabs, err := auto.debugger.GetTargets() if err != nil { return err } - auto.tabLock.Lock() for _, tab := range tabs { auto.tabs[tab.Target.Id] = NewTab(tab) @@ -70,12 +73,38 @@ func (auto *AutoGcd) Start() error { } // Closes all tabs and shuts down the browser. -func (auto *AutoGcd) Shutdown() { +func (auto *AutoGcd) Shutdown() error { auto.tabLock.Lock() for _, tab := range auto.tabs { auto.debugger.CloseTab(tab.ChromeTarget) } auto.tabLock.Unlock() + auto.debugger.ExitProcess() + if auto.settings.removeUserDir == true { + return os.RemoveAll(auto.settings.userDir) + } + return nil +} + +// Refreshs our internal list of tabs and return all tabs +func (auto *AutoGcd) RefreshTabList() (map[string]*Tab, error) { + + knownTabs := auto.GetAllTabs() + knownIds := make(map[string]struct{}, len(knownTabs)) + for _, v := range knownTabs { + knownIds[v.Target.Id] = struct{}{} + } + newTabs, err := auto.debugger.GetNewTargets(knownIds) + if err != nil { + return nil, err + } + + auto.tabLock.Lock() + for _, newTab := range newTabs { + auto.tabs[newTab.Target.Id] = NewTab(newTab) + } + auto.tabLock.Unlock() + return auto.GetAllTabs(), nil } // Returns the first "visual" tab. diff --git a/autogcd_test.go b/autogcd_test.go index ea7d3b2..f5a6f6a 100644 --- a/autogcd_test.go +++ b/autogcd_test.go @@ -18,6 +18,8 @@ var ( testServerAddr string ) +var testStartupFlags = []string{"--disable-new-tab-first-run", "--no-first-run", "--disable-popup-blocking"} + func init() { flag.StringVar(&testPath, "chrome", "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe", "path to Xvfb") flag.StringVar(&testDir, "dir", "C:\\temp\\", "user directory") @@ -111,7 +113,8 @@ func TestCloseTab(t *testing.T) { func testDefaultStartup(t *testing.T) *AutoGcd { s := NewSettings(testPath, testRandomDir(t)) - s.AddStartupFlags([]string{"--disable-new-tab-first-run", "--no-first-run"}) + s.RemoveUserDir(true) + s.AddStartupFlags(testStartupFlags) s.SetDebuggerPort(testRandomPort(t)) auto := NewAutoGcd(s) if err := auto.Start(); err != nil { diff --git a/settings.go b/settings.go index d53363d..1a16480 100644 --- a/settings.go +++ b/settings.go @@ -6,13 +6,14 @@ import ( ) type Settings struct { - timeout time.Duration - chromePath string - chromeHost string - chromePort string - userDir string - extensions []string - flags []string + timeout time.Duration + chromePath string // path to chrome + chromeHost string // can really only be localhost + chromePort string // port to chrome debugger + userDir string // the user directory to use + removeUserDir bool // should we delete the user directory on shutdown? + extensions []string // custom extensions to load + flags []string // custom os.Environ flags to use to start the chrome process } func NewSettings(chromePath, userDir string) *Settings { @@ -20,6 +21,7 @@ func NewSettings(chromePath, userDir string) *Settings { s.chromePath = chromePath s.chromePort = "9222" s.userDir = userDir + s.removeUserDir = false s.extensions = make([]string, 0) s.flags = make([]string, 0) return s @@ -37,6 +39,11 @@ func (s *Settings) SetStartTimeout(timeout time.Duration) { s.timeout = timeout } +// On Shutdown, deletes the userDir and files if true. +func (s *Settings) RemoveUserDir(shouldRemove bool) { + s.removeUserDir = true +} + func (s *Settings) AddStartupFlags(flags []string) { s.flags = append(s.flags, flags...) } diff --git a/tab_test.go b/tab_test.go index 9338b6b..427501b 100644 --- a/tab_test.go +++ b/tab_test.go @@ -340,6 +340,36 @@ func TestTabNetworkListen(t *testing.T) { } } +func TestTabWindows(t *testing.T) { + testAuto := testDefaultStartup(t) + defer testAuto.Shutdown() + tab, err := testAuto.GetTab() + if err != nil { + t.Fatalf("error getting tab") + } + if _, err := tab.Navigate(testServerAddr + "window_main.html"); err != nil { + t.Fatalf("error opening first window") + } + + ele, _, err := tab.GetElementById("mainwindow") + if err != nil { + t.Fatalf("error getting mainwindow element") + } + ele.WaitForReady() + tabs := testAuto.GetAllTabs() + if err != nil { + t.Fatalf("error getting tabs") + } + + newTabs, err := testAuto.RefreshTabList() + if err != nil { + t.Fatalf("Error getting new tabs") + } + + t.Logf("%d unknown tabs found!", len(newTabs)-len(tabs)) + +} + func testTimeout(t *testing.T, duration time.Duration) { time.Sleep(duration) t.Fatalf("timed out waiting for console message") diff --git a/testdata/window_main.html b/testdata/window_main.html new file mode 100644 index 0000000..cda7394 --- /dev/null +++ b/testdata/window_main.html @@ -0,0 +1,16 @@ + + + + +window main + + + +
main window
+ + diff --git a/testdata/window_sub1.html b/testdata/window_sub1.html new file mode 100644 index 0000000..bfc57ad --- /dev/null +++ b/testdata/window_sub1.html @@ -0,0 +1,16 @@ + + + + +window main + + + +
sub 1 window
+ + diff --git a/testdata/window_sub2.html b/testdata/window_sub2.html new file mode 100644 index 0000000..b84b9d0 --- /dev/null +++ b/testdata/window_sub2.html @@ -0,0 +1,14 @@ + + + + +window main + + + +
sub 2 window
+ +