From 27ee92c8721f982b79432689dbcb5439bb4fadc2 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 5 Jun 2019 20:57:55 +0100 Subject: extend the monkey test tooling to cope with ssl certificate windows --- test/monkey-see-monkey-do | 24 +++++++++++++- test/monkey-tests/sslcert.yaml | 33 +++++++++++++++++++ test/monkey_driver.py | 72 ++++++++++++++++++++++++++++++++++++++++++ test/monkeyfarmer.py | 46 ++++++++++++++++++++++++++- 4 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 test/monkey-tests/sslcert.yaml diff --git a/test/monkey-see-monkey-do b/test/monkey-see-monkey-do index 84a935e90..68c75a339 100755 --- a/test/monkey-see-monkey-do +++ b/test/monkey-see-monkey-do @@ -8,7 +8,7 @@ MONKEY_PATH="./nsmonkey" # Otherwise let's begin... import sys - +import getopt import yaml import multiprocessing as mp @@ -40,6 +40,8 @@ def child_run_test(parts): else: sys.stdout = oldout sys.stderr = olderr + if verbose == True: + print("STDOUT:\n{}\n", outcapture.getvalue()) def run_test(parts): p = mp.Process(target=child_run_test, args=(parts, )) @@ -47,6 +49,26 @@ def run_test(parts): p.join() return p.exitcode +def print_usage(): + print('Usage:') + print(' ' + sys.argv[0] + ' [-v] [-h]') + +def parse_argv(argv): + verbose=False + try: + opts, args = getopt.getopt(argv,"hv",[]) + except getopt.GetoptError: + print_usage() + sys.exit(2) + for opt, arg in opts: + if opt == '-h': + print_usage() + sys.exit() + elif opt in ("-v", "--verbose"): + verbose=True + return verbose + +verbose = parse_argv(sys.argv[1:]) print("Fetching tests...") index = request.urlopen(BASE_PATH) diff --git a/test/monkey-tests/sslcert.yaml b/test/monkey-tests/sslcert.yaml new file mode 100644 index 000000000..96df2d651 --- /dev/null +++ b/test/monkey-tests/sslcert.yaml @@ -0,0 +1,33 @@ +title: Test the SSL certificate error functionality +group: real-world +steps: +- action: launch + language: en +- action: window-new + tag: win1 +- action: navigate + window: win1 + url: https://badssl.com/ +- action: block + conditions: + - window: win1 + status: complete +- action: plot-check + window: win1 + checks: + - text-contains: "badssl.com" +- action: navigate + window: win1 + url: https://expired.badssl.com/ +- action: block + conditions: + - window: win1 + status: complete +- action: plot-check + window: win1 + checks: + - text-not-contains: "expired. badssl.com" +- action: window-close + window: win1 +- action: quit + diff --git a/test/monkey_driver.py b/test/monkey_driver.py index f1ba115c0..30570942e 100755 --- a/test/monkey_driver.py +++ b/test/monkey_driver.py @@ -1,4 +1,24 @@ #!/usr/bin/python3 +# +# Copyright 2019 Daniel Silverstone +# +# This file is part of NetSurf, http://www.netsurf-browser.org/ +# +# NetSurf is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# NetSurf is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +runs tests in monkey as defined in a yaml file +""" import sys, getopt, yaml, time @@ -8,6 +28,7 @@ class DriverBrowser(Browser): def __init__(self, *args, **kwargs): super(DriverBrowser, self).__init__(*args, **kwargs) self.auth = [] + self.cert = [] def add_auth(self, url, realm, username, password): self.auth.append((url, realm, username, password)) @@ -57,6 +78,42 @@ class DriverBrowser(Browser): print("401: No candidate found, cancelling login box") logwin.destroy() + def add_cert(self, url): + # add sll certificate error exception + self.cert.append(url) + + def remove_cert(self, url): + keep = [] + def matches(a,b): + if a is None or b is None: + return True + return a == b + for iurl in self.cert: + if not (matches(url, iurl)): + keep.append(iurl) + self.cert = keep + + def handle_ready_sslcert(self, cwin): + def matches(a,b): + if a is None or b is None: + return True + return a == b + candidates = [] + for url in self.cert: + score = 0 + if matches(url, cwin.url): + score += 1 + if score > 0: + candidates.append((score, url)) + if candidates: + candidates.sort() + (score, url) = candidates[-1] + print("SSLCert: Found candidate {} with score {}".format(url, score)) + cwin.go() + else: + print("SSLCert: No candidate found, cancelling sslcert box") + cwin.destroy() + def print_usage(): print('Usage:') print(' ' + sys.argv[0] + ' -m -t ') @@ -317,6 +374,19 @@ def run_test_step_action_remove_auth(ctx, step): browser.remove_auth(step.get("url"), step.get("realm"), step.get("username"), step.get("password")) +def run_test_step_action_add_cert(ctx, step): + print(get_indent(ctx) + "Action:" + step["action"]) + assert_browser(ctx) + browser = ctx['browser'] + browser.add_cert(step.get("url")) + + +def run_test_step_action_remove_cert(ctx, step): + print(get_indent(ctx) + "Action:" + step["action"]) + assert_browser(ctx) + browser = ctx['browser'] + browser.remove_cert(step.get("url")) + def run_test_step_action_clear_log(ctx, step): print(get_indent(ctx) + "Action: " + step["action"]) @@ -378,6 +448,8 @@ step_handlers = { "plot-check": run_test_step_action_plot_check, "add-auth": run_test_step_action_add_auth, "remove-auth": run_test_step_action_remove_auth, + "add-cert": run_test_step_action_add_cert, + "remove-cert": run_test_step_action_remove_cert, "clear-log": run_test_step_action_clear_log, "wait-log": run_test_step_action_wait_log, "js-exec": run_test_step_action_js_exec, diff --git a/test/monkeyfarmer.py b/test/monkeyfarmer.py index 0bae027a2..cbd979cad 100644 --- a/test/monkeyfarmer.py +++ b/test/monkeyfarmer.py @@ -1,4 +1,4 @@ -# Copyright 2017, 2018 Daniel Silverstone +# Copyright 2017-2019 Daniel Silverstone # # This file is part of NetSurf, http://www.netsurf-browser.org/ # @@ -126,6 +126,7 @@ class Browser: self.farmer = MonkeyFarmer(monkey_cmd=monkey_cmd, online=self.on_monkey_line, quiet=quiet) self.windows = {} self.logins = {} + self.sslcerts = {} self.current_draw_target = None self.started = False self.stopped = False @@ -189,6 +190,18 @@ class Browser: if win.alive and win.ready: self.handle_ready_login(win) + def handle_SSLCERT(self, action, _lwin, winid, *args): + if action == "VERIFY": + new_win = SSLCertWindow(self, winid, *args) + self.sslcerts[winid] = new_win + self.handle_ready_sslcert(new_win) + else: + win = self.sslcerts.get(winid, None) + if win is None: + print(" Unknown ssl cert window id {}".format(winid)) + else: + win.handle(action, *args) + def handle_PLOT(self, *args): if self.current_draw_target is not None: self.current_draw_target.handle_plot(*args) @@ -208,6 +221,34 @@ class Browser: # Override this method to do useful stuff lwin.destroy() +class SSLCertWindow: + def __init__(self, browser, winid, _url, *url): + self.alive = True + self.browser = browser + self.winid = winid + self.url = " ".join(url) + + def handle(self, action, _str="STR", *rest): + content = " ".join(rest) + if action == "DESTROY": + self.alive = False + else: + raise AssertionError("Unknown action {} for sslcert window".format(action)) + + def _wait_dead(self): + while self.alive: + self.browser.farmer.loop(once=True) + + def go(self): + assert(self.alive) + self.browser.farmer.tell_monkey("SSLCERT GO {}".format(self.winid)) + self._wait_dead() + + def destroy(self): + assert(self.alive) + self.browser.farmer.tell_monkey("SSLCERT DESTROY {}".format(self.winid)) + self._wait_dead() + class LoginWindow: def __init__(self, browser, winid, _url, *url): self.alive = True @@ -493,6 +534,9 @@ if __name__ == '__main__': lwin.send_password("bar") lwin.go() + def handle_ready_sslcert(self, cwin): + cwin.destroy() + browser = FooBarLogin(quiet=True) win = browser.new_window() win.load_page("https://httpbin.org/basic-auth/foo/bar") -- cgit v1.2.3