Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import time
2import json
3import yaml
4import toml
5import tempfile
6import urllib.parse
7import requests
8from subprocess import DEVNULL
9from lxml import etree
10import logging.config
13progn_schema = yaml.safe_load("""
14type: array
15items: {type: object}
16""")
19def Base_progn(self, param):
20 """
21 - name: subroutine
22 progn:
23 - name: debug1
24 echo: hello world
25 - name: debug2
26 echo: good-bye world
27 """
28 self.lock.release()
29 ret = self.run(param)
30 self.lock.acquire()
31 return ret
34var_schema = {"type": "object"}
37def Base_var(self, param):
38 """
39 - name: set variables
40 var:
41 key1: value1
42 key2:
43 - value2.1
44 - value2.2
45 """
46 self.variables.update(param)
49var_if_not_schema = var_schema
52def Base_var_if_not(self, param):
53 """
54 - name: set variables
55 var_if_not:
56 key1: value1
57 key2:
58 - value2.1
59 - value2.2
60 """
61 for k, v in param.items():
62 if k not in self.variables:
63 self.variables[k] = v
66var_from_schema = yaml.safe_load("""
67type: object
68properties:
69 yaml: {type: string}
70 json: {type: string}
71 toml: {type: string}
72""")
75def Base_var_from(self, param):
76 """
77 - name: set variables from file
78 var_from:
79 yaml: filename
80 json: filename
81 toml: filename
82 """
83 if "yaml" in param:
84 with open(param.get("yaml")) as f:
85 self.do_var(yaml.safe_load(f))
86 if "json" in param:
87 with open(param.get("json")) as f:
88 self.do_var(json.load(f))
89 if "toml" in param:
90 with open(param.get("toml")) as f:
91 self.do_var(toml.load(f))
94var_from_if_not_schema = var_from_schema
97def Base_var_from_if_not(self, param):
98 """
99 - name: set variables from file
100 var_from_if_not:
101 yaml: filename
102 json: filename
103 toml: filename
104 """
105 if "yaml" in param:
106 with open(param.get("yaml")) as f:
107 self.do_var_if_not(yaml.safe_load(f))
108 if "json" in param:
109 with open(param.get("json")) as f:
110 self.do_var_if_not(json.load(f))
111 if "toml" in param:
112 with open(param.get("toml")) as f:
113 self.do_var_if_not(toml.load(f))
116def Base_runcmd(self, param):
117 """
118 - name: run shell command
119 runcmd: echo hello
120 - name: word count
121 runcmd:
122 stdin: "{{page_source}}"
123 cmd: wc
124 """
125 if isinstance(param, (list, tuple, str)):
126 self.log.debug("run: %s", param)
127 out = self.runcmd(param)
128 self.log.debug("result: %s", out)
129 return out
130 elif isinstance(param, dict):
131 cmd = param.get("cmd", None)
132 stdin = param.get("stdin", None)
133 stdout = param.get("stdout", None)
134 stderr = param.get("stderr", None)
135 if cmd is None:
136 raise Exception("missing cmd: %s" % (param))
137 if stdin is not None:
138 sin = tempfile.TemporaryFile()
139 sin.write(stdin.encode("utf-8"))
140 sin.seek(0)
141 else:
142 sin = DEVNULL
143 if stderr is not None:
144 serr = open(stderr)
145 else:
146 serr = DEVNULL
147 out = self.runcmd(cmd, stdin=sin, stderr=serr)
148 if serr != DEVNULL:
149 serr.close()
150 if sin != DEVNULL:
151 sin.close()
152 self.log.info("result: %s", out)
153 if stdout is not None:
154 with open(stdout, "w") as f:
155 f.write(out)
156 return out
157 else:
158 raise Exception("runcmd: param not supported: %s" % (param))
161echo_schema = yaml.safe_load("""
162oneOf:
163 - type: string
164 - "$ref": "#/definitions/common/textvalue"
165""")
168def Base_echo(self, param):
169 """
170 - name: debug message
171 echo:
172 text: hello world
173 """
174 if isinstance(param, str):
175 self.log.info("echo %s", param)
176 return param
177 else:
178 txt = self.getvalue(param)
179 self.log.info("echo %s", txt)
180 return txt
183sleep_schema = {"type": "integer"}
186def Base_sleep(self, param):
187 """
188 - name: wait 10 sec
189 sleep: 10
190 """
191 self.lock.release()
192 time.sleep(int(param))
193 self.lock.acquire()
196include_schema = yaml.safe_load("""
197oneOf:
198 - type: string
199 - type: array
200 items: {type: string}
201""")
204def Base_include(self, param):
205 """
206 - name: run other file
207 include: filename.yaml
208 - name: run other files
209 include:
210 - file1.yaml
211 - file2.yaml
212 """
213 if isinstance(param, (list, tuple)):
214 for fname in param:
215 self.log.info("loading %s", fname)
216 with open(fname) as f:
217 self.lock.release()
218 ret = self.run(yaml.safe_load(f))
219 self.lock.acquire()
220 return ret
221 elif isinstance(param, str):
222 self.log.info("loading %s", param)
223 with open(param) as f:
224 self.lock.release()
225 ret = self.run(yaml.safe_load(f))
226 self.lock.acquire()
227 return ret
228 else:
229 raise Exception("cannot load: %s" % (param))
232def Base_config(self, param):
233 """
234 - name: configuration
235 config:
236 wait: 10
237 cookie:
238 var1: val1
239 window:
240 width: 600
241 height: 480
242 """
243 if "wait" in param:
244 self.log.debug("implicitly wait %s sec", param.get("wait"))
245 self.driver.implicitly_wait(param.get("wait"))
246 if "cookie" in param:
247 self.log.debug("cookie update: %s" % (param.get("cookie", {}).keys()))
248 self.driver.add_cookie(param.get("cookie"))
249 if "window" in param:
250 self.log.info("window size update: %s" % (param.get("window", {})))
251 win = param.get("window")
252 if win.get("maximize", False):
253 self.driver.maximize_window()
254 else:
255 x = win.get("x")
256 y = win.get("y")
257 if x is not None and y is not None:
258 self.log.debug("set window pos: x=%d, y=%d", x, y)
259 self.driver.set_window_position(x, y)
260 width = win.get("width")
261 height = win.get("height")
262 if width is not None and height is not None:
263 self.log.debug("set window size: width=%d, height=%d", width, height)
264 self.driver.set_window_size(width, height)
265 if "log" in param:
266 logconf = param.get("log")
267 if isinstance(logconf, str):
268 logging.config.fileConfig(logconf)
269 elif isinstance(logconf, dict):
270 logging.config.dictConfig(logconf)
271 else:
272 raise Exception("config.log must be filename or dict: %s", param.get("log"))
273 if "page_load_timeout" in param:
274 self.driver.set_page_load_timeout(param.get("page_load_timeout"))
275 if "implicitly_wait" in param:
276 self.driver.implicitly_wait(param.get("implicitly_wait"))
277 if "script_timeout" in param:
278 self.driver.set_script_timeout(param.get("script_timeout"))
281assert_schema = {"$ref": "#/definitions/common/condition"}
284def Base_assert(self, param):
285 """
286 - name: check condition
287 assert:
288 eq:
289 - "{{selenible_version}}"
290 - "0.1"
291 """
292 if not self.eval_param(param):
293 self.log.error("condition failed: %s", param)
294 raise Exception("condition failed: %s" % (param))
297assert_not_schema = assert_schema
300def Base_assert_not(self, param):
301 """
302 - name: check condition
303 assert_not:
304 eq:
305 - "{{selenible_version}}"
306 - "0.3"
307 """
308 if self.eval_param(param):
309 self.log.error("condition(not) failed: %s", param)
310 raise Exception("condition(not) failed: %s" % (param))
313xslt_schema = yaml.safe_load("""
314type: object
315properties:
316 proc: {type: string}
317 output: {type: string}
318""")
321def Base_xslt(self, param):
322 """
323 - name: transform
324 xslt:
325 proc: |
326 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
327 <xsl:template match="/">
328 <xsl:value-of select="//a/@href" />
329 </xsl:template>
330 </xsl:stylesheet>
331 output: outfile.txt
332 """
333 if isinstance(param, dict):
334 proc = etree.XSLT(etree.XML(param.get("proc", "")))
335 output = param.get("output", None)
336 elem = self.findmany(param)
337 if elem == [None]:
338 p = etree.parse(self.driver.page_source)
339 rst = [str(proc(p))]
340 else:
341 rst = []
342 for e in elem:
343 p = etree.parse(e.get_attribute("innerHTML"))
344 rst.append(str(proc(p)))
345 if output is not None:
346 with open(output, "w") as f:
347 for x in rst:
348 f.write(str(x))
349 return rst
350 else:
351 raise Exception("invalid parameter: %s" % (param))
354download_schema = yaml.safe_load("""
355type: object
356properties:
357 url: {type: string}
358 method: {type: string}
359 query: {type: object}
360 headers: {type: object}
361 json: {type: boolean}
362 output: {type: string}
363""")
366def Base_download(self, param):
367 """
368 - name: download file using python-requests
369 download:
370 url: "{{current_url}}/file1"
371 method: get
372 query:
373 var1: val1
374 timeout: 10
375 json: false
376 output: outfile.txt
377 """
378 url = param.get("url", None)
379 if url is None:
380 raise Exception("url mut set: %s" % (param))
381 parsed_url = urllib.parse.urlparse(url)
382 self.log.debug("URL parsed: %s", parsed_url)
383 method = param.get("method", "get")
384 query = param.get("query", None)
385 cookies = self.driver.get_cookies()
386 headers = param.get("headers", None)
387 timeout = param.get("timeout", None)
388 is_json = param.get("json", False)
389 sess = requests.Session()
390 output = param.get("output", None)
391 for ck in cookies:
392 sess.cookies.set(ck.get("name"), ck.get("value"),
393 path=ck.get("path", "/"), domain=ck.get("domain", ""),
394 secure=ck.get("secure", False))
395 resp = sess.request(method, url, params=query, headers=headers, timeout=timeout)
396 if output is not None:
397 with open(output, "wb") as f:
398 f.write(resp.content)
399 if is_json:
400 return resp.json()
401 return resp.text
404set_schema = yaml.safe_load("""
405anyOf:
406 - "$ref": "#/definitions/common/locator"
407 - "$ref": "#/definitions/common/textvalue"
408 - type: object
409 properties:
410 parseHTML: {type: boolean}
411""")
414def Base_set(self, param):
415 """
416 - name: set variable (v1="blabla")
417 register: v1
418 set:
419 text: blabla
420 - name: set variable v2
421 register: v2
422 set:
423 xpath: '//a'
424 parseHTML: true
425 - name: echo
426 echo: 'v1={{v1}}, v2={%for x in v2%}{{x.get("href")}},{%endfor%}'
427 """
428 res = self.getvalue(param)
429 if res is not None:
430 return self.return_element(param, res)
431 return self.return_element(param, self.findmany(param))