Skip to content

Commit

Permalink
a function to create TabManager which controls tabs in multiple windows
Browse files Browse the repository at this point in the history
  • Loading branch information
Ronmi committed Mar 7, 2019
1 parent fd66af2 commit 6615532
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 0 deletions.
82 changes: 82 additions & 0 deletions tabmgr/winmanager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package tabmgr

import (
"errors"
"sync"

"github.com/raohwork/marionette-go/mnclient"
"github.com/raohwork/marionette-go/mnsender"
)

// WindowManager creates a TabManager instance to control tabs in multiple window
//
// The actual tab name will be "window_name:tab_name"
//
// w, _ := WindowManager(sender, map[string][]string{"w1": {"t1", "t2"}})
// tab := w.GetTab("w1:t1")
//
// It creates/closes windows and tabs automatically, does not cooperate with other
// managers well.
func WindowManager(
s mnsender.Sender, windows map[string][]string,
) (ret *TabManager, err error) {
if len(windows) == 0 {
panic(errors.New("windows cannot be empty"))
}
for _, tabs := range windows {
if len(tabs) == 0 {
panic(errors.New("tabs cannot be empty"))
}
}

cl := &mnclient.Commander{Sender: s}
creator := mnclient.NewTabCreator(cl)

// ensuring number of windows
curWin, err := cl.GetChromeWindowHandles()
if err != nil {
return
}
curWin, err = creator.EnsureWindowNumber(curWin, len(windows))
if err != nil {
return
}

// create mapping of window name => window handle
winMap := map[string]string{}
idx := 0
for name, _ := range windows {
winMap[name] = curWin[idx]
idx++
}

// get current tab mapping
curTabs, err := creator.CurrentTabMapping()
if err != nil {
return
}

// ensuring number of tabs in each window
for name, winH := range winMap {
have := curTabs[winH]
want := len(windows[name])
got, e := creator.EnsureTabNumber(have, want)
if e != nil {
err = e
return
}
curTabs[winH] = got
}

// create tab name => handle mapping
allTabs := map[string]string{}
for wname, tabs := range windows {
winH := winMap[wname]
for idx, tname := range tabs {
allTabs[wname+":"+tname] = curTabs[winH][idx]
}
}

ret = NewWithMap(s, allTabs, &sync.Mutex{})
return
}
48 changes: 48 additions & 0 deletions tabmgr/winmanager_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package tabmgr

import "testing"

func TestNewWindowMgr3Win(t *testing.T) {
sender, _ := connect(t)
defer sender.Close()

windows := map[string][]string{
"w1": {"t1"},
"w2": {"t1", "t2"},
"w3": {"t1", "t2", "t3"},
}
wm, err := WindowManager(sender, windows)
if err != nil {
t.Fatalf("cannot create window manager: %s", err)
}

getw := func(id string) (hwin string) {
w := wm.GetTab(id)
if w == nil {
t.Fatalf("cannot find %s", id)
}
hwin, err := w.GetChromeWindowHandle()
if err != nil {
t.Fatalf("cannot get window handle of %s: %s", id, err)
}
return
}

w1h := getw("w1:t1")
w2h := getw("w2:t1")
w3h := getw("w3:t1")

if w1h == w2h || w2h == w3h || w2h == w1h {
t.Fatalf("same window detected: %s, %s, %s", w1h, w2h, w3h)
}

for _, tn := range []string{"t2", "t3"} {
if h := getw("w3:" + tn); h != w3h {
t.Fatalf("tab w3:%s not with w3:t1", tn)
}
}

if h := getw("w2:t2"); h != w2h {
t.Fatal("tab w2:t2 not with w2:t1")
}
}

0 comments on commit 6615532

Please sign in to comment.