UNPKG

4.79 kBtext/coffeescriptView Raw
1map = require("lodash/map")
2pick = require("lodash/pick")
3once = require("lodash/once")
4Promise = require("bluebird")
5
6HOST = "CHANGE_ME_HOST"
7PATH = "CHANGE_ME_PATH"
8
9firstOrNull = (cookies) ->
10 ## normalize into null when empty array
11 cookies[0] ? null
12
13connect = (host, path, io) ->
14 io ?= global.io
15
16 ## bail if io isnt defined
17 return if not io
18
19 listenToCookieChanges = once ->
20 chrome.cookies.onChanged.addListener (info) ->
21 if info.cause isnt "overwrite"
22 client.emit("automation:push:request", "change:cookie", info)
23
24 fail = (id, err) ->
25 client.emit("automation:response", id, {
26 __error: err.message
27 __stack: err.stack
28 __name: err.name
29 })
30
31 invoke = (method, id, args...) ->
32 respond = (data) ->
33 client.emit("automation:response", id, {response: data})
34
35 Promise.try ->
36 automation[method].apply(automation, args.concat(respond))
37 .catch (err) ->
38 fail(id, err)
39
40 ## cannot use required socket here due
41 ## to bug in socket io client with browserify
42 client = io.connect(host, {path: path})
43
44 client.on "automation:request", (id, msg, data) ->
45 switch msg
46 when "get:cookies"
47 invoke("getCookies", id, data)
48 when "get:cookie"
49 invoke("getCookie", id, data)
50 when "set:cookie"
51 invoke("setCookie", id, data)
52 when "clear:cookies"
53 invoke("clearCookies", id, data)
54 when "clear:cookie"
55 invoke("clearCookie", id, data)
56 when "is:automation:connected"
57 invoke("verify", id, data)
58 when "focus:browser:window"
59 invoke("focus", id)
60 when "take:screenshot"
61 invoke("takeScreenshot", id)
62 else
63 fail(id, {message: "No handler registered for: '#{msg}'"})
64
65 client.on "connect", ->
66 listenToCookieChanges()
67
68 client.emit("automation:connected")
69
70 return client
71
72## initially connect
73connect(HOST, PATH, global.io)
74
75automation = {
76 connect: connect
77
78 getUrl: (cookie = {}) ->
79 prefix = if cookie.secure then "https://" else "http://"
80 prefix + cookie.domain + cookie.path
81
82 clear: (filter = {}) ->
83 clear = (cookie) =>
84 new Promise (resolve, reject) =>
85 url = @getUrl(cookie)
86 chrome.cookies.remove {url: url, name: cookie.name}, (details) ->
87 if details
88 resolve(cookie)
89 else
90 reject(chrome.runtime.lastError)
91
92 @getAll(filter)
93 .map(clear)
94
95 getAll: (filter = {}) ->
96 get = ->
97 new Promise (resolve) ->
98 chrome.cookies.getAll(filter, resolve)
99
100 get()
101
102 getCookies: (filter, fn) ->
103 @getAll(filter)
104 .then(fn)
105
106 getCookie: (filter, fn) ->
107 @getAll(filter)
108 .then(firstOrNull)
109 .then(fn)
110
111 setCookie: (props = {}, fn) ->
112 set = =>
113 new Promise (resolve, reject) =>
114 props.url = @getUrl(props)
115 chrome.cookies.set props, (details) ->
116 if details
117 resolve(details)
118 else
119 reject(chrome.runtime.lastError)
120
121 set()
122 .then(fn)
123
124 clearCookie: (filter, fn) ->
125 @clear(filter)
126 .then(firstOrNull)
127 .then(fn)
128
129 clearCookies: (filter, fn) ->
130 @clear(filter)
131 .then(fn)
132
133 focus: (fn) ->
134 ## lets just make this simple and whatever is the current
135 ## window bring that into focus
136 ##
137 ## TODO: if we REALLY want to be nice its possible we can
138 ## figure out the exact window that's running Cypress but
139 ## that's too much work with too little value at the moment
140 chrome.windows.getCurrent (window) ->
141 chrome.windows.update window.id, {focused: true}, ->
142 fn()
143
144 query: (host, data) ->
145 ## query for tabs which match
146 ## our expected host
147 ## ie: http://localhost:2020/*
148 url = host + "/*"
149 code = "var s; (s = document.getElementById('#{data.element}')) && s.textContent"
150
151 query = ->
152 new Promise (resolve) ->
153 chrome.tabs.query({url: url, windowType: "normal"}, resolve)
154
155 queryTab = (tab) ->
156 new Promise (resolve, reject) ->
157 chrome.tabs.executeScript tab.id, {code: code}, (result) ->
158 if result and result[0] is data.string
159 resolve()
160 else
161 reject(new Error)
162
163 query()
164 .then (tabs) ->
165 ## generate array of promises
166 map(tabs, queryTab)
167 .any()
168
169 verify: (data, fn) ->
170 @query(HOST, data)
171 .then(fn)
172
173 lastFocusedWindow: ->
174 new Promise (resolve) ->
175 chrome.windows.getLastFocused(resolve)
176
177 takeScreenshot: (fn) ->
178 @lastFocusedWindow()
179 .then (win) ->
180 new Promise (resolve, reject) ->
181 chrome.tabs.captureVisibleTab win.id, {format: "png"}, (dataUrl) ->
182 if dataUrl
183 resolve(dataUrl)
184 else
185 reject(chrome.runtime.lastError)
186 .then(fn)
187}
188
189module.exports = automation