Beispiel #1
0
class VirtualDisplay(Service, Singletone):
    """
    Selenium executor
    :type virtual_display: Display
    """

    SHARED_VIRTUAL_DISPLAY = {}

    def __init__(self):
        super(VirtualDisplay, self).__init__()
        self.virtual_display = None

    def get_virtual_display(self):
        return self.virtual_display

    def set_virtual_display(self):
        if is_windows():
            self.log.warning(
                "Cannot have virtual display on Windows, ignoring")
        else:
            if self.engine in VirtualDisplay.SHARED_VIRTUAL_DISPLAY:
                self.virtual_display = VirtualDisplay.SHARED_VIRTUAL_DISPLAY[
                    self.engine]
            else:
                width = self.parameters.get("width", 1024)
                height = self.parameters.get("height", 768)
                self.virtual_display = Display(size=(width, height))
                msg = "Starting virtual display[%s]: %s"
                self.log.info(msg, self.virtual_display.size,
                              self.virtual_display.new_display_var)
                self.virtual_display.start()
                VirtualDisplay.SHARED_VIRTUAL_DISPLAY[
                    self.engine] = self.virtual_display

    def free_virtual_display(self):
        if self.virtual_display and self.virtual_display.is_alive():
            self.virtual_display.stop()
        if self.engine in VirtualDisplay.SHARED_VIRTUAL_DISPLAY:
            del VirtualDisplay.SHARED_VIRTUAL_DISPLAY[self.engine]

    def startup(self):
        self.set_virtual_display()

    def check_virtual_display(self):
        if self.virtual_display:
            if not self.virtual_display.is_alive():
                self.log.info("Virtual display out: %s",
                              self.virtual_display.stdout)
                self.log.warning("Virtual display err: %s",
                                 self.virtual_display.stderr)
                raise TaurusInternalException("Virtual display failed: %s" %
                                              self.virtual_display.return_code)

    def check(self):
        self.check_virtual_display()
        return False

    def shutdown(self):
        self.free_virtual_display()
Beispiel #2
0
class VirtualDisplay(Service, Singletone):
    """
    Selenium executor
    :type virtual_display: Display
    """

    SHARED_VIRTUAL_DISPLAY = None

    def __init__(self):
        super(VirtualDisplay, self).__init__()
        self.virtual_display = None

    def get_virtual_display(self):
        return self.virtual_display

    def set_virtual_display(self):
        if is_windows():
            self.log.warning("Cannot have virtual display on Windows, ignoring")
            return

        if VirtualDisplay.SHARED_VIRTUAL_DISPLAY:
            self.virtual_display = VirtualDisplay.SHARED_VIRTUAL_DISPLAY
        else:
            width = self.parameters.get("width", 1024)
            height = self.parameters.get("height", 768)
            self.virtual_display = Display(size=(width, height))
            msg = "Starting virtual display[%s]: %s"
            self.log.info(msg, self.virtual_display.size, self.virtual_display.new_display_var)
            self.virtual_display.start()
            VirtualDisplay.SHARED_VIRTUAL_DISPLAY = self.virtual_display

            self.engine.shared_env.set({'DISPLAY': os.environ['DISPLAY']})   # backward compatibility

    def free_virtual_display(self):
        if self.virtual_display and self.virtual_display.is_alive():
            self.virtual_display.stop()
        if VirtualDisplay.SHARED_VIRTUAL_DISPLAY:
            VirtualDisplay.SHARED_VIRTUAL_DISPLAY = None

    def startup(self):
        self.set_virtual_display()

    def check_virtual_display(self):
        if self.virtual_display:
            if not self.virtual_display.is_alive():
                self.log.info("Virtual display out: %s", self.virtual_display.stdout)
                self.log.warning("Virtual display err: %s", self.virtual_display.stderr)
                raise TaurusInternalException("Virtual display failed: %s" % self.virtual_display.return_code)

    def check(self):
        self.check_virtual_display()
        return False

    def shutdown(self):
        self.free_virtual_display()
Beispiel #3
0
class SeleniumExecutor(ScenarioExecutor, WidgetProvider, FileLister):
    """
    Selenium executor
    :type virtual_display: Display
    :type runner: AbstractTestRunner
    """
    SELENIUM_DOWNLOAD_LINK = "http://selenium-release.storage.googleapis.com/{version}/" \
                             "selenium-server-standalone-{version}.0.jar"
    SELENIUM_VERSION = "2.53"

    JUNIT_DOWNLOAD_LINK = "http://search.maven.org/remotecontent?filepath=junit/junit/{version}/junit-{version}.jar"
    JUNIT_VERSION = "4.12"
    JUNIT_MIRRORS_SOURCE = "http://search.maven.org/solrsearch/select?q=g%3A%22junit%22%20AND%20a%3A%22junit%22%20" \
                           "AND%20v%3A%22{version}%22&rows=20&wt=json".format(version=JUNIT_VERSION)

    HAMCREST_DOWNLOAD_LINK = "https://hamcrest.googlecode.com/files/hamcrest-core-1.3.jar"

    SUPPORTED_TYPES = [".py", ".jar", ".java"]

    SHARED_VIRTUAL_DISPLAY = {}

    def __init__(self):
        super(SeleniumExecutor, self).__init__()
        self.additional_env = {}
        self.virtual_display = None
        self.start_time = None
        self.end_time = None
        self.runner = None
        self.widget = None
        self.reader = None
        self.kpi_file = None
        self.err_jtl = None
        self.runner_working_dir = None
        self.scenario = None

    def set_virtual_display(self):
        display_conf = self.settings.get("virtual-display")
        if display_conf:
            if is_windows():
                self.log.warning("Cannot have virtual display on Windows, ignoring")
            else:
                if self.engine in SeleniumExecutor.SHARED_VIRTUAL_DISPLAY:
                    self.virtual_display = SeleniumExecutor.SHARED_VIRTUAL_DISPLAY[self.engine]
                else:
                    width = display_conf.get("width", 1024)
                    height = display_conf.get("height", 768)
                    self.virtual_display = Display(size=(width, height))
                    msg = "Starting virtual display[%s]: %s"
                    self.log.info(msg, self.virtual_display.size, self.virtual_display.new_display_var)
                    self.virtual_display.start()
                    SeleniumExecutor.SHARED_VIRTUAL_DISPLAY[self.engine] = self.virtual_display

    def free_virtual_display(self):
        if self.virtual_display and self.virtual_display.is_alive():
            self.virtual_display.stop()
        if self.engine in SeleniumExecutor.SHARED_VIRTUAL_DISPLAY:
            del SeleniumExecutor.SHARED_VIRTUAL_DISPLAY[self.engine]

    def _get_script_path(self):
        script = self.scenario.get(Scenario.SCRIPT)
        if not script:
            return None
        return self.engine.find_file(script)

    def prepare(self):
        self.set_virtual_display()
        self.scenario = self.get_scenario()
        self._verify_script()
        self.kpi_file = self.engine.create_artifact("selenium_tests_report", ".csv")
        self.err_jtl = self.engine.create_artifact("selenium_tests_err", ".xml")
        script_path = self._get_script_path()
        script_type = self.detect_script_type(script_path)

        runner_config = BetterDict()

        if script_type == ".py":
            runner_class = NoseTester
            runner_config.merge(self.settings.get("selenium-tools").get("nose"))
        else:  # script_type == ".jar" or script_type == ".java":
            runner_class = JUnitTester
            runner_config.merge(self.settings.get("selenium-tools").get("junit"))
            runner_config['props-file'] = self.engine.create_artifact("customrunner", ".properties")

        runner_config["script-type"] = script_type
        if self.runner_working_dir is None:
            self.runner_working_dir = self.engine.create_artifact(runner_config.get("working-dir", "classes"), "")
        runner_config["working-dir"] = self.runner_working_dir
        runner_config.get("artifacts-dir", self.engine.artifacts_dir)
        runner_config.get("working-dir", self.runner_working_dir)
        runner_config.get("report-file", self.kpi_file)
        runner_config.get("err-file", self.err_jtl)
        runner_config.get("stdout", self.engine.create_artifact("junit", ".out"))
        runner_config.get("stderr", self.engine.create_artifact("junit", ".err"))

        self._cp_resource_files(self.runner_working_dir)

        self.runner = runner_class(runner_config, self)
        self.runner.prepare()
        self.reader = JTLReader(self.kpi_file, self.log, self.err_jtl)
        if isinstance(self.engine.aggregator, ConsolidatingAggregator):
            self.engine.aggregator.add_underling(self.reader)

    def _verify_script(self):
        if not self.scenario.get(Scenario.SCRIPT):
            if self.scenario.get("requests"):
                self.scenario[Scenario.SCRIPT] = self.__tests_from_requests()
            else:
                raise RuntimeError("Nothing to test, no requests were provided in scenario")

    def _cp_resource_files(self, runner_working_dir):
        """
        :return:
        """
        script = self._get_script_path()

        if script is not None:
            if os.path.isdir(script):
                shutil.copytree(script, runner_working_dir)
            else:
                os.makedirs(runner_working_dir)
                shutil.copy2(script, runner_working_dir)

    @staticmethod
    def detect_script_type(script_path):
        """
        checks if script is java or python
        if it's folder or single script

        :param script_path: str
        :return:
        """
        if not isinstance(script_path, string_types) and not isinstance(script_path, text_type):
            raise ValueError("Nothing to test, no files were provided in scenario")

        if not os.path.exists(script_path):
            raise ValueError("Script %s doesn't exist" % script_path)

        file_types = set()

        if os.path.isfile(script_path):  # regular file received
            file_types.add(os.path.splitext(script_path)[1].lower())
        else:  # dir received: check files
            for walk_rec in os.walk(script_path):
                for file_name in walk_rec[2]:
                    file_types.add(os.path.splitext(file_name)[1].lower())

        if '.java' in file_types:
            file_ext = '.java'
        elif '.py' in file_types:
            file_ext = '.py'
        elif '.jar' in file_types:
            file_ext = '.jar'
        else:
            raise ValueError("Unsupported script type: %s" % script_path)

        return file_ext

    def startup(self):
        """
        Start runner
        :return:
        """
        self.start_time = time.time()
        self.runner.env = self.additional_env
        self.runner.run_tests()

    def check(self):
        """
        check if test completed
        :return:
        """
        if self.widget:
            self.widget.update()

        if self.virtual_display:
            if not self.virtual_display.is_alive():
                self.log.info("Virtual display out: %s", self.virtual_display.stdout)
                self.log.warning("Virtual display err: %s", self.virtual_display.stderr)
                raise RuntimeError("Virtual display failed: %s" % self.virtual_display.return_code)

        return self.runner.is_finished()

    def shutdown(self):
        """
        shutdown test_runner
        :return:
        """
        self.runner.shutdown()

        if self.start_time:
            self.end_time = time.time()
            self.log.debug("Selenium tests ran for %s seconds", self.end_time - self.start_time)

    def post_process(self):
        self.free_virtual_display()

        if self.reader and not self.reader.read_records:
            raise RuntimeWarning("Empty results, most likely Selenium failed")

    def get_widget(self):
        if not self.widget:
            self.widget = SeleniumWidget(self.scenario.get(Scenario.SCRIPT), self.runner.settings.get("stdout"))
        return self.widget

    def resource_files(self):
        if not self.scenario:
            self.scenario = self.get_scenario()

        if Scenario.SCRIPT not in self.scenario:
            return []

        script_path = self._get_script_path()

        if os.path.isdir(script_path):
            files = next(os.walk(script_path))
            resources = [os.path.join(files[0], f) for f in files[2]]
        else:
            resources = [script_path]

        return resources

    def __tests_from_requests(self):
        filename = self.engine.create_artifact("test_requests", ".py")
        nose_test = SeleniumScriptBuilder(self.scenario, self.log)
        if self.virtual_display:
            nose_test.window_size = self.virtual_display.size
        nose_test.gen_test_case()
        nose_test.save(filename)
        return filename
Beispiel #4
0
class SeleniumExecutor(ScenarioExecutor, WidgetProvider, FileLister):
    """
    Selenium executor
    :type virtual_display: Display
    :type runner: AbstractTestRunner
    """
    SELENIUM_DOWNLOAD_LINK = "http://selenium-release.storage.googleapis.com/{version}/" \
                             "selenium-server-standalone-{version}.0.jar"
    SELENIUM_VERSION = "2.53"

    JUNIT_DOWNLOAD_LINK = "http://search.maven.org/remotecontent?filepath=junit/junit/" \
                          "{version}/junit-{version}.jar"
    JUNIT_VERSION = "4.12"
    JUNIT_MIRRORS_SOURCE = "http://search.maven.org/solrsearch/select?q=g%3A%22junit%22%20AND%20a%3A%22" \
                           "junit%22%20AND%20v%3A%22{version}%22&rows=20&wt=json".format(version=JUNIT_VERSION)

    HAMCREST_DOWNLOAD_LINK = "http://search.maven.org/remotecontent?filepath=org/hamcrest/hamcrest-core" \
                             "/1.3/hamcrest-core-1.3.jar"

    JSON_JAR_DOWNLOAD_LINK = "http://search.maven.org/remotecontent?filepath=org/json/json/20160810/json-20160810.jar"

    SUPPORTED_TYPES = [".py", ".jar", ".java"]

    SHARED_VIRTUAL_DISPLAY = {}

    def __init__(self):
        super(SeleniumExecutor, self).__init__()
        self.additional_env = {}
        self.virtual_display = None
        self.end_time = None
        self.runner = None
        self.reader = None
        self.report_file = None
        self.runner_working_dir = None
        self.scenario = None
        self.script = None
        self.self_generated_script = False
        self.generated_methods = BetterDict()

    def set_virtual_display(self):
        display_conf = self.settings.get("virtual-display")
        if display_conf:
            if is_windows():
                self.log.warning(
                    "Cannot have virtual display on Windows, ignoring")
            else:
                if self.engine in SeleniumExecutor.SHARED_VIRTUAL_DISPLAY:
                    self.virtual_display = SeleniumExecutor.SHARED_VIRTUAL_DISPLAY[
                        self.engine]
                else:
                    width = display_conf.get("width", 1024)
                    height = display_conf.get("height", 768)
                    self.virtual_display = Display(size=(width, height))
                    msg = "Starting virtual display[%s]: %s"
                    self.log.info(msg, self.virtual_display.size,
                                  self.virtual_display.new_display_var)
                    self.virtual_display.start()
                    SeleniumExecutor.SHARED_VIRTUAL_DISPLAY[
                        self.engine] = self.virtual_display

    def free_virtual_display(self):
        if self.virtual_display and self.virtual_display.is_alive():
            self.virtual_display.stop()
        if self.engine in SeleniumExecutor.SHARED_VIRTUAL_DISPLAY:
            del SeleniumExecutor.SHARED_VIRTUAL_DISPLAY[self.engine]

    def get_script_path(self, scenario=None):
        if scenario:
            return super(SeleniumExecutor, self).get_script_path(scenario)
        else:
            return self.engine.find_file(self.script)

    def _create_runner(self, working_dir, report_file):
        script_path = self.get_script_path()
        script_type = self.detect_script_type(script_path)
        runner_config = BetterDict()

        if script_type == ".py":
            runner_class = NoseTester
            runner_config.merge(
                self.settings.get("selenium-tools").get("nose"))
        else:  # script_type == ".jar" or script_type == ".java":
            runner_class = JUnitTester
            runner_config.merge(
                self.settings.get("selenium-tools").get("junit"))
            runner_config['props-file'] = self.engine.create_artifact(
                "customrunner", ".properties")

        runner_config["script-type"] = script_type
        runner_config["working-dir"] = working_dir
        runner_config.get("artifacts-dir", self.engine.artifacts_dir)
        runner_config.get("report-file", report_file)
        runner_config.get("stdout",
                          self.engine.create_artifact("junit", ".out"))
        runner_config.get("stderr",
                          self.engine.create_artifact("junit", ".err"))
        return runner_class(runner_config, self)

    def _create_reader(self, report_file):
        return LoadSamplesReader(report_file, self.log, self.generated_methods)

    def prepare(self):
        self.set_virtual_display()
        self.scenario = self.get_scenario()
        self._verify_script()

        self.runner_working_dir = self.engine.create_artifact("classes", "")
        self.report_file = self.engine.create_artifact("selenium_tests_report",
                                                       ".ldjson")
        self.runner = self._create_runner(self.runner_working_dir,
                                          self.report_file)

        self._cp_resource_files(self.runner_working_dir)

        self.runner.prepare()
        self.reader = self._create_reader(self.report_file)
        if isinstance(self.engine.aggregator, ConsolidatingAggregator):
            self.engine.aggregator.add_underling(self.reader)

    def _verify_script(self):
        if Scenario.SCRIPT in self.scenario and self.scenario.get(
                Scenario.SCRIPT):
            self.script = self.scenario.get(Scenario.SCRIPT)
        elif "requests" in self.scenario:
            self.script = self.__tests_from_requests()
            self.self_generated_script = True
        else:
            raise ValueError(
                "Nothing to test, no requests were provided in scenario")

    def _cp_resource_files(self, runner_working_dir):
        script = self.get_script_path()

        if os.path.isdir(script):
            shutil.copytree(script, runner_working_dir)
        else:
            os.makedirs(runner_working_dir)
            if self.self_generated_script:
                shutil.move(script, runner_working_dir)
            else:
                script_type = self.detect_script_type(script)
                script_name = os.path.basename(script)
                if script_type == ".py" and not script_name.lower().startswith(
                        'test'):
                    target_name = 'test_' + script_name
                    msg = "Script '%s' won't be discovered by nosetests, renaming script to %s"
                    self.log.warning(msg, script_name, target_name)
                else:
                    target_name = script_name
                target_path = os.path.join(runner_working_dir, target_name)
                shutil.copy2(script, target_path)

    @staticmethod
    def detect_script_type(script_path):
        if not isinstance(script_path, string_types) and not isinstance(
                script_path, text_type):
            raise ValueError(
                "Nothing to test, no files were provided in scenario")

        if not os.path.exists(script_path):
            raise ValueError("Script %s doesn't exist" % script_path)

        file_types = set()

        if os.path.isfile(script_path):  # regular file received
            file_types.add(os.path.splitext(script_path)[1].lower())
        else:  # dir received: check contained files
            for file_name in get_files_recursive(script_path):
                file_types.add(os.path.splitext(file_name)[1].lower())

        if '.java' in file_types:
            file_ext = '.java'
        elif '.py' in file_types:
            file_ext = '.py'
        elif '.jar' in file_types:
            file_ext = '.jar'
        else:
            raise ValueError("Unsupported script type: %s" % script_path)

        return file_ext

    def startup(self):
        """
        Start runner
        :return:
        """
        self.start_time = time.time()
        self.runner.env = self.additional_env
        self.runner.run_tests()

    def check_virtual_display(self):
        if self.virtual_display:
            if not self.virtual_display.is_alive():
                self.log.info("Virtual display out: %s",
                              self.virtual_display.stdout)
                self.log.warning("Virtual display err: %s",
                                 self.virtual_display.stderr)
                raise RuntimeError("Virtual display failed: %s" %
                                   self.virtual_display.return_code)

    def check(self):
        """
        check if test completed
        :return:
        """
        if self.widget:
            self.widget.update()

        self.check_virtual_display()

        return self.runner.is_finished()

    def report_test_duration(self):
        if self.start_time:
            self.end_time = time.time()
            self.log.debug("Selenium tests ran for %s seconds",
                           self.end_time - self.start_time)

    def shutdown(self):
        """
        shutdown test_runner
        :return:
        """
        self.runner.shutdown()
        self.report_test_duration()

    def post_process(self):
        self.free_virtual_display()

        if self.reader and not self.reader.read_records:
            raise RuntimeWarning("Empty results, most likely Selenium failed")

    def get_widget(self):
        if not self.widget:
            self.widget = SeleniumWidget(self.script,
                                         self.runner.settings.get("stdout"))
        return self.widget

    def resource_files(self):
        self.scenario = self.get_scenario()
        self._verify_script()
        script_path = self.get_script_path()
        resources = []
        if script_path is not None:
            resources.append(script_path)
        return resources

    def __tests_from_requests(self):
        filename = self.engine.create_artifact("test_requests", ".py")
        wdlog = self.engine.create_artifact('webdriver', '.log')
        nose_test = SeleniumScriptBuilder(self.scenario, self.log, wdlog)
        if self.virtual_display:
            nose_test.window_size = self.virtual_display.size
        self.generated_methods.merge(nose_test.gen_test_case())
        nose_test.save(filename)
        return filename
Beispiel #5
0
class SeleniumExecutor(AbstractSeleniumExecutor, WidgetProvider, FileLister):
    """
    Selenium executor
    :type virtual_display: Display
    :type runner: SubprocessedExecutor
    """

    SUPPORTED_RUNNERS = ["nose", "junit", "testng", "rspec", "mocha"]

    def __init__(self):
        super(SeleniumExecutor, self).__init__()
        self.additional_env = {}
        self.virtual_display = None
        self.end_time = None
        self.runner = None
        self.report_file = None
        self.scenario = None
        self.script = None
        self.generated_methods = BetterDict()
        self.runner_working_dir = None
        self.register_reader = True

    def get_virtual_display(self):
        return self.virtual_display

    def add_env(self, env):
        self.additional_env.update(env)

    def set_virtual_display(self):
        display_conf = self.settings.get("virtual-display")
        if display_conf:
            if is_windows():
                self.log.warning("Cannot have virtual display on Windows, ignoring")
            else:
                if self.engine in SeleniumExecutor.SHARED_VIRTUAL_DISPLAY:
                    self.virtual_display = SeleniumExecutor.SHARED_VIRTUAL_DISPLAY[self.engine]
                else:
                    width = display_conf.get("width", 1024)
                    height = display_conf.get("height", 768)
                    self.virtual_display = Display(size=(width, height))
                    msg = "Starting virtual display[%s]: %s"
                    self.log.info(msg, self.virtual_display.size, self.virtual_display.new_display_var)
                    self.virtual_display.start()
                    SeleniumExecutor.SHARED_VIRTUAL_DISPLAY[self.engine] = self.virtual_display

    def free_virtual_display(self):
        if self.virtual_display and self.virtual_display.is_alive():
            self.virtual_display.stop()
        if self.engine in SeleniumExecutor.SHARED_VIRTUAL_DISPLAY:
            del SeleniumExecutor.SHARED_VIRTUAL_DISPLAY[self.engine]

    def get_runner_working_dir(self):
        if self.runner_working_dir is None:
            self.runner_working_dir = self.engine.create_artifact("classes", "")
        return self.runner_working_dir

    def _get_testng_xml(self):
        if 'testng-xml' in self.scenario:
            testng_xml = self.scenario.get('testng-xml')
            if testng_xml:
                return testng_xml
            else:
                return None  # empty value for switch off testng.xml path autodetect

        script_path = self.get_script_path()
        if script_path:
            script_dir = get_full_path(script_path, step_up=1)
            testng_xml = os.path.join(script_dir, 'testng.xml')
            if os.path.exists(testng_xml):
                self.log.info("Detected testng.xml file at %s", testng_xml)
                self.scenario['testng-xml'] = testng_xml
                return testng_xml

        return None

    def _create_runner(self, report_file):
        script_type = self.detect_script_type()
        runner = self.engine.instantiate_module(script_type)
        runner.parameters = self.parameters
        runner.provisioning = self.provisioning
        runner.execution = self.execution
        runner.execution['executor'] = script_type

        if script_type == "nose":
            runner.generated_methods = self.generated_methods
            runner.execution["test-mode"] = "selenium"
        elif script_type == "junit":
            pass
        elif script_type == "testng":
            testng_config = self._get_testng_xml()
            if testng_config:
                runner.execution['testng-xml'] = self.engine.find_file(testng_config)
        elif script_type == "rspec":
            pass
        elif script_type == "mocha":
            pass
        else:
            raise TaurusConfigError("Unsupported script type: %s" % script_type)

        runner.execution["report-file"] = report_file  # TODO: shouldn't it be the field?
        return runner

    def _register_reader(self, report_file):
        if self.engine.is_functional_mode():
            reader = FuncSamplesReader(report_file, self.engine, self.log, self.generated_methods)
            if isinstance(self.engine.aggregator, FunctionalAggregator):
                self.engine.aggregator.add_underling(reader)
        else:
            reader = LoadSamplesReader(report_file, self.log, self.generated_methods)
            if isinstance(self.engine.aggregator, ConsolidatingAggregator):
                self.engine.aggregator.add_underling(reader)
        return reader

    def prepare(self):
        if self.get_load().concurrency and self.get_load().concurrency > 1:
            msg = 'Selenium supports concurrency in cloud provisioning mode only\n'
            msg += 'For details look at http://gettaurus.org/docs/Cloud.md'
            self.log.warning(msg)
        self.set_virtual_display()
        self.scenario = self.get_scenario()
        self.script = self.get_script_path()

        self.report_file = self.engine.create_artifact("selenium_tests_report", ".ldjson")
        self.runner = self._create_runner(self.report_file)
        self.runner.prepare()
        if isinstance(self.runner, NoseTester):
            self.script = self.runner._script
        if self.register_reader:
            self.reader = self._register_reader(self.report_file)

    def detect_script_type(self):
        if not self.script and "requests" in self.scenario:
            return "nose"

        if not os.path.exists(self.script):
            raise TaurusConfigError("Script '%s' doesn't exist" % self.script)

        if "runner" in self.execution:
            runner = self.execution["runner"]
            if runner not in SeleniumExecutor.SUPPORTED_RUNNERS:
                msg = "Runner '%s' is not supported. Supported runners: %s"
                raise TaurusConfigError(msg % (runner, SeleniumExecutor.SUPPORTED_RUNNERS))
            self.log.debug("Using script type: %s", runner)
            return runner

        file_types = set()

        if os.path.isfile(self.script):  # regular file received
            file_types.add(os.path.splitext(self.script)[1].lower())
        else:  # dir received: check contained files
            for file_name in get_files_recursive(self.script):
                file_types.add(os.path.splitext(file_name)[1].lower())

        if '.java' in file_types or '.jar' in file_types:
            if self._get_testng_xml() is not None:
                script_type = 'testng'
            else:
                script_type = 'junit'
        elif '.py' in file_types:
            script_type = 'nose'
        elif '.rb' in file_types:
            script_type = 'rspec'
        elif '.js' in file_types:
            script_type = 'mocha'
        else:
            raise TaurusConfigError("Unsupported script type: %s" % self.script)

        self.log.debug("Detected script type: %s", script_type)

        return script_type

    def startup(self):
        """
        Start runner
        :return:
        """
        self.start_time = time.time()
        self.runner.env = self.additional_env
        self.runner.startup()

    def check_virtual_display(self):
        if self.virtual_display:
            if not self.virtual_display.is_alive():
                self.log.info("Virtual display out: %s", self.virtual_display.stdout)
                self.log.warning("Virtual display err: %s", self.virtual_display.stderr)
                raise TaurusInternalException("Virtual display failed: %s" % self.virtual_display.return_code)

    def check(self):
        """
        check if test completed
        :return:
        """
        if self.widget:
            self.widget.update()

        self.check_virtual_display()

        return self.runner.check()

    def report_test_duration(self):
        if self.start_time:
            self.end_time = time.time()
            self.log.debug("Selenium tests ran for %s seconds", self.end_time - self.start_time)

    def shutdown(self):
        """
        shutdown test_runner
        :return:
        """
        self.runner.shutdown()
        self.report_test_duration()

    def post_process(self):
        if os.path.exists("geckodriver.log"):
            self.engine.existing_artifact("geckodriver.log", True)
        self.free_virtual_display()

    def has_results(self):
        if self.reader and self.reader.read_records:
            return True
        else:
            return False

    def get_widget(self):
        if not self.widget:
            self.widget = SeleniumWidget(self.script, self.runner._stdout_file)
        return self.widget

    def resource_files(self):
        resources = []

        self.scenario = self.get_scenario()
        script = self.scenario.get(Scenario.SCRIPT, None)
        if script:
            resources.append(script)

        resources.extend(self.scenario.get("additional-classpath", []))
        resources.extend(self.settings.get("additional-classpath", []))

        testng_config = self._get_testng_xml()
        if testng_config:
            resources.append(testng_config)

        return resources
Beispiel #6
0
class SeleniumExecutor(ScenarioExecutor, WidgetProvider, FileLister):
    """
    Selenium executor
    :type virtual_display: Display
    :type runner: AbstractTestRunner
    """
    SELENIUM_DOWNLOAD_LINK = "http://selenium-release.storage.googleapis.com/{version}/" \
                             "selenium-server-standalone-{version}.0.jar"
    SELENIUM_VERSION = "2.53"

    JUNIT_DOWNLOAD_LINK = "http://search.maven.org/remotecontent?filepath=junit/junit/" \
                          "{version}/junit-{version}.jar"
    JUNIT_VERSION = "4.12"
    JUNIT_MIRRORS_SOURCE = "http://search.maven.org/solrsearch/select?q=g%3A%22junit%22%20AND%20a%3A%22" \
                           "junit%22%20AND%20v%3A%22{version}%22&rows=20&wt=json".format(version=JUNIT_VERSION)

    HAMCREST_DOWNLOAD_LINK = "http://search.maven.org/remotecontent?filepath=org/hamcrest/hamcrest-core" \
                             "/1.3/hamcrest-core-1.3.jar"

    JSON_JAR_DOWNLOAD_LINK = "http://search.maven.org/remotecontent?filepath=org/json/json/20160810/json-20160810.jar"

    SUPPORTED_TYPES = ["python-nose", "java-junit", "ruby-rspec"]

    SHARED_VIRTUAL_DISPLAY = {}

    def __init__(self):
        super(SeleniumExecutor, self).__init__()
        self.additional_env = {}
        self.virtual_display = None
        self.end_time = None
        self.runner = None
        self.report_file = None
        self.scenario = None
        self.script = None
        self.self_generated_script = False
        self.generated_methods = BetterDict()
        self.runner_working_dir = None

    def set_virtual_display(self):
        display_conf = self.settings.get("virtual-display")
        if display_conf:
            if is_windows():
                self.log.warning("Cannot have virtual display on Windows, ignoring")
            else:
                if self.engine in SeleniumExecutor.SHARED_VIRTUAL_DISPLAY:
                    self.virtual_display = SeleniumExecutor.SHARED_VIRTUAL_DISPLAY[self.engine]
                else:
                    width = display_conf.get("width", 1024)
                    height = display_conf.get("height", 768)
                    self.virtual_display = Display(size=(width, height))
                    msg = "Starting virtual display[%s]: %s"
                    self.log.info(msg, self.virtual_display.size, self.virtual_display.new_display_var)
                    self.virtual_display.start()
                    SeleniumExecutor.SHARED_VIRTUAL_DISPLAY[self.engine] = self.virtual_display

    def free_virtual_display(self):
        if self.virtual_display and self.virtual_display.is_alive():
            self.virtual_display.stop()
        if self.engine in SeleniumExecutor.SHARED_VIRTUAL_DISPLAY:
            del SeleniumExecutor.SHARED_VIRTUAL_DISPLAY[self.engine]

    def get_script_path(self, scenario=None):
        if scenario:
            return super(SeleniumExecutor, self).get_script_path(scenario)
        else:
            return self.engine.find_file(self.script)

    def get_runner_working_dir(self):
        if self.runner_working_dir is None:
            self.runner_working_dir = self.engine.create_artifact("classes", "")
        return self.runner_working_dir

    def _create_runner(self, report_file):
        script_path = self.get_script_path()
        script_type = self.detect_script_type(script_path)

        runner_config = BetterDict()

        if script_type == "python-nose":
            runner_class = NoseTester
            runner_config.merge(self.settings.get("selenium-tools").get("nose"))
        elif script_type == "java-junit":
            runner_class = JUnitTester
            runner_config.merge(self.settings.get("selenium-tools").get("junit"))
            runner_config['working-dir'] = self.get_runner_working_dir()
            runner_config['props-file'] = self.engine.create_artifact("customrunner", ".properties")
        elif script_type == "ruby-rspec":
            runner_class = RSpecTester
        elif script_type == "js-mocha":
            runner_class = MochaTester
        else:
            raise ValueError("Unsupported script type: %s" % script_type)

        runner_config["script"] = script_path
        runner_config["script-type"] = script_type
        runner_config["artifacts-dir"] = self.engine.artifacts_dir
        runner_config["report-file"] = report_file
        runner_config["stdout"] = self.engine.create_artifact("selenium", ".out")
        runner_config["stderr"] = self.engine.create_artifact("selenium", ".err")
        return runner_class(runner_config, self)

    def _register_reader(self, report_file):
        if self.engine.is_functional_mode():
            reader = FuncSamplesReader(report_file, self.log, self.generated_methods)
            if isinstance(self.engine.aggregator, FunctionalAggregator):
                self.engine.aggregator.add_underling(reader)
        else:
            reader = LoadSamplesReader(report_file, self.log, self.generated_methods)
            if isinstance(self.engine.aggregator, ConsolidatingAggregator):
                self.engine.aggregator.add_underling(reader)
        return reader

    def prepare(self):
        self.set_virtual_display()
        self.scenario = self.get_scenario()
        self.__setup_script()

        self.report_file = self.engine.create_artifact("selenium_tests_report", ".ldjson")
        self.runner = self._create_runner(self.report_file)

        self.runner.prepare()
        self.reader = self._register_reader(self.report_file)

    def __setup_script(self):
        if Scenario.SCRIPT in self.scenario and self.scenario.get(Scenario.SCRIPT):
            self.script = self.scenario.get(Scenario.SCRIPT)
        elif "requests" in self.scenario:
            self.script = self.__tests_from_requests()
            self.self_generated_script = True
        else:
            raise ValueError("Nothing to test, no requests were provided in scenario")

    def detect_script_type(self, script_path):
        if not isinstance(script_path, string_types) and not isinstance(script_path, text_type):
            raise ValueError("Nothing to test, no files were provided in scenario")

        if not os.path.exists(script_path):
            raise ValueError("Script %s doesn't exist" % script_path)

        if "language" in self.execution:
            lang = self.execution["language"]
            if lang not in self.SUPPORTED_TYPES:
                tmpl = "Language '%s' is not supported. Supported languages are: %s"
                raise ValueError(tmpl % (lang, self.SUPPORTED_TYPES))
            self.log.debug("Using script type: %s", lang)
            return lang

        file_types = set()

        if os.path.isfile(script_path):  # regular file received
            file_types.add(os.path.splitext(script_path)[1].lower())
        else:  # dir received: check contained files
            for file_name in get_files_recursive(script_path):
                file_types.add(os.path.splitext(file_name)[1].lower())

        if '.java' in file_types or '.jar' in file_types:
            script_type = 'java-junit'
        elif '.py' in file_types:
            script_type = 'python-nose'
        elif '.rb' in file_types:
            script_type = 'ruby-rspec'
        elif '.js' in file_types:
            script_type = 'js-mocha'
        else:
            raise ValueError("Unsupported script type: %s" % script_path)

        self.log.debug("Detected script type: %s", script_type)

        return script_type

    def startup(self):
        """
        Start runner
        :return:
        """
        self.start_time = time.time()
        self.runner.env = self.additional_env
        self.runner.run_tests()

    def check_virtual_display(self):
        if self.virtual_display:
            if not self.virtual_display.is_alive():
                self.log.info("Virtual display out: %s", self.virtual_display.stdout)
                self.log.warning("Virtual display err: %s", self.virtual_display.stderr)
                raise RuntimeError("Virtual display failed: %s" % self.virtual_display.return_code)

    def check(self):
        """
        check if test completed
        :return:
        """
        if self.widget:
            self.widget.update()

        self.check_virtual_display()

        return self.runner.is_finished()

    def report_test_duration(self):
        if self.start_time:
            self.end_time = time.time()
            self.log.debug("Selenium tests ran for %s seconds", self.end_time - self.start_time)

    def shutdown(self):
        """
        shutdown test_runner
        :return:
        """
        self.runner.shutdown()
        self.report_test_duration()

    def post_process(self):
        self.free_virtual_display()

    def has_results(self):
        if self.reader and self.reader.read_records:
            return True
        else:
            return False

    def get_widget(self):
        if not self.widget:
            self.widget = SeleniumWidget(self.script, self.runner.settings.get("stdout"))
        return self.widget

    def resource_files(self):
        self.scenario = self.get_scenario()
        self.__setup_script()
        script_path = self.get_script_path()
        resources = []
        if script_path is not None:
            resources.append(script_path)
        return resources

    def __tests_from_requests(self):
        filename = self.engine.create_artifact("test_requests", ".py")
        wdlog = self.engine.create_artifact('webdriver', '.log')
        nose_test = SeleniumScriptBuilder(self.scenario, self.log, wdlog)
        if self.virtual_display:
            nose_test.window_size = self.virtual_display.size
        self.generated_methods.merge(nose_test.build_source_code())
        nose_test.save(filename)
        return filename
Beispiel #7
0
class SeleniumExecutor(AbstractSeleniumExecutor, WidgetProvider, FileLister):
    """
    Selenium executor
    :type virtual_display: Display
    :type runner: SubprocessedExecutor
    """

    SUPPORTED_RUNNERS = ["nose", "junit", "testng", "rspec", "mocha"]

    def __init__(self):
        super(SeleniumExecutor, self).__init__()
        self.additional_env = {}
        self.virtual_display = None
        self.end_time = None
        self.runner = None
        self.script = None
        self.generated_methods = BetterDict()
        self.runner_working_dir = None

    def get_virtual_display(self):
        return self.virtual_display

    def add_env(self, env):
        self.additional_env.update(env)

    def set_virtual_display(self):
        display_conf = self.settings.get("virtual-display")
        if display_conf:
            if is_windows():
                self.log.warning(
                    "Cannot have virtual display on Windows, ignoring")
            else:
                if self.engine in SeleniumExecutor.SHARED_VIRTUAL_DISPLAY:
                    self.virtual_display = SeleniumExecutor.SHARED_VIRTUAL_DISPLAY[
                        self.engine]
                else:
                    width = display_conf.get("width", 1024)
                    height = display_conf.get("height", 768)
                    self.virtual_display = Display(size=(width, height))
                    msg = "Starting virtual display[%s]: %s"
                    self.log.info(msg, self.virtual_display.size,
                                  self.virtual_display.new_display_var)
                    self.virtual_display.start()
                    SeleniumExecutor.SHARED_VIRTUAL_DISPLAY[
                        self.engine] = self.virtual_display

    def free_virtual_display(self):
        if self.virtual_display and self.virtual_display.is_alive():
            self.virtual_display.stop()
        if self.engine in SeleniumExecutor.SHARED_VIRTUAL_DISPLAY:
            del SeleniumExecutor.SHARED_VIRTUAL_DISPLAY[self.engine]

    def get_runner_working_dir(self):
        if self.runner_working_dir is None:
            self.runner_working_dir = self.engine.create_artifact(
                "classes", "")
        return self.runner_working_dir

    def create_runner(self):
        runner_type = self.get_runner_type()
        self.runner = self.engine.instantiate_module(runner_type)

        # todo: deprecated, remove it later
        self.runner.settings.merge(
            self.settings.get('selenium-tools').get(runner_type))

        self.runner.parameters = self.parameters
        self.runner.provisioning = self.provisioning
        self.runner.execution = self.execution
        self.runner.execution['executor'] = runner_type

        if runner_type == "nose":
            self.runner.execution["test-mode"] = "selenium"

    def prepare(self):
        if self.get_load().concurrency and self.get_load().concurrency > 1:
            msg = 'Selenium supports concurrency in cloud provisioning mode only\n'
            msg += 'For details look at http://gettaurus.org/docs/Cloud.md'
            self.log.warning(msg)
        self.set_virtual_display()
        self.create_runner()
        self.runner.prepare()
        self.script = self.runner.script

    def get_runner_type(self):
        if "runner" in self.execution:
            runner = self.execution["runner"]
            if runner not in SeleniumExecutor.SUPPORTED_RUNNERS:
                msg = "Runner '%s' is not supported. Supported runners: %s"
                raise TaurusConfigError(
                    msg % (runner, SeleniumExecutor.SUPPORTED_RUNNERS))
            self.log.debug("Using script type: %s", runner)
            return runner

        script_name = self.get_script_path()
        if script_name:
            return self.detect_script_type(script_name)
        else:
            if "requests" in self.get_scenario():
                return "nose"
            else:
                raise TaurusConfigError(
                    "You must specify either script or list of requests to run Selenium"
                )

    def resource_files(self):
        self.create_runner()
        return self.runner.resource_files()

    def detect_script_type(self, script_name):
        if not os.path.exists(script_name):
            raise TaurusConfigError("Script '%s' doesn't exist" % script_name)

        file_types = set()

        # gather file extensions and choose script_type according to priority
        if os.path.isfile(script_name):  # regular file received
            file_types.add(os.path.splitext(script_name)[1].lower())
        else:  # dir received: check contained files
            for file_name in get_files_recursive(script_name):
                file_types.add(os.path.splitext(file_name)[1].lower())

        if '.java' in file_types or '.jar' in file_types:
            # todo: next detection logic is duplicated in TestNGTester - can we avoid it?
            script_dir = get_full_path(self.get_script_path(), step_up=1)
            if os.path.exists(os.path.join(
                    script_dir, 'testng.xml')) or self.execution.get(
                        'testng-xml', None):
                script_type = 'testng'
            else:
                script_type = 'junit'
        elif '.py' in file_types:
            script_type = 'nose'
        elif '.rb' in file_types:
            script_type = 'rspec'
        elif '.js' in file_types:
            script_type = 'mocha'
        else:
            raise TaurusConfigError(
                "Supported script files not found, script detection is failed")

        self.log.debug("Detected script type: %s", script_type)

        return script_type

    def startup(self):
        """
        Start runner
        :return:
        """
        self.start_time = time.time()
        self.runner.env = self.additional_env
        self.runner.startup()

    def check_virtual_display(self):
        if self.virtual_display:
            if not self.virtual_display.is_alive():
                self.log.info("Virtual display out: %s",
                              self.virtual_display.stdout)
                self.log.warning("Virtual display err: %s",
                                 self.virtual_display.stderr)
                raise TaurusInternalException("Virtual display failed: %s" %
                                              self.virtual_display.return_code)

    def check(self):
        """
        check if test completed
        :return:
        """
        if self.widget:
            self.widget.update()

        self.check_virtual_display()

        return self.runner.check()

    def report_test_duration(self):
        if self.start_time:
            self.end_time = time.time()
            self.log.debug("Selenium tests ran for %s seconds",
                           self.end_time - self.start_time)

    def shutdown(self):
        """
        shutdown test_runner
        :return:
        """
        self.runner.shutdown()
        self.report_test_duration()

    def post_process(self):
        if os.path.exists("geckodriver.log"):
            self.engine.existing_artifact("geckodriver.log", True)
        self.free_virtual_display()

    def has_results(self):
        return self.runner.has_results()

    def get_widget(self):
        if not self.widget:
            self.widget = SeleniumWidget(self.script, self.runner.stdout_file)
        return self.widget
Beispiel #8
0
class SeleniumExecutor(ScenarioExecutor, WidgetProvider, FileLister):
    """
    Selenium executor
    :type virtual_display: Display
    """
    SELENIUM_DOWNLOAD_LINK = "http://selenium-release.storage.googleapis.com/{version}/" \
                             "selenium-server-standalone-{version}.0.jar"
    SELENIUM_VERSION = "2.48"

    JUNIT_DOWNLOAD_LINK = "http://search.maven.org/remotecontent?filepath=junit/junit/{version}/junit-{version}.jar"
    JUNIT_VERSION = "4.12"
    JUNIT_MIRRORS_SOURCE = "http://search.maven.org/solrsearch/select?q=g%3A%22junit%22%20AND%20a%3A%22junit%22%20" \
                           "AND%20v%3A%22{version}%22&rows=20&wt=json".format(version=JUNIT_VERSION)

    HAMCREST_DOWNLOAD_LINK = "https://hamcrest.googlecode.com/files/hamcrest-core-1.3.jar"

    SUPPORTED_TYPES = [".py", ".jar", ".java"]

    def __init__(self):
        super(SeleniumExecutor, self).__init__()
        self.virtual_display = None
        self.start_time = None
        self.end_time = None
        self.runner = None
        self.widget = None
        self.reader = None
        self.kpi_file = None
        self.err_jtl = None
        self.runner_working_dir = None
        self.scenario = None

    def prepare(self):
        display_conf = self.settings.get("virtual-display")
        if display_conf:
            if is_windows():
                self.log.warning("Cannot have virtual display on Windows, ignoring")
            else:
                width = display_conf.get("width", 1024)
                height = display_conf.get("height", 768)
                self.virtual_display = Display(size=(width, height))

        self.scenario = self.get_scenario()
        self._verify_script()
        self.kpi_file = self.engine.create_artifact("selenium_tests_report", ".csv")
        self.err_jtl = self.engine.create_artifact("selenium_tests_err", ".xml")
        script_type = self.detect_script_type(self.scenario.get(Scenario.SCRIPT))

        if script_type == ".py":
            runner_class = NoseTester
            runner_config = self.settings.get("selenium-tools").get("nose")
        elif script_type == ".jar" or script_type == ".java":
            runner_class = JUnitTester
            runner_config = self.settings.get("selenium-tools").get("junit")
            runner_config['props-file'] = self.engine.create_artifact("customrunner", ".properties")
        else:
            raise ValueError("Unsupported script type: %s" % script_type)

        runner_config["script-type"] = script_type
        self.runner_working_dir = self.engine.create_artifact(runner_config.get("working-dir", "classes"), "")
        runner_config["working-dir"] = self.runner_working_dir
        runner_config.get("artifacts-dir", self.engine.artifacts_dir)
        runner_config.get("working-dir", self.runner_working_dir)
        runner_config.get("report-file", self.kpi_file)
        runner_config.get("err-file", self.err_jtl)
        runner_config.get("stdout", self.engine.create_artifact("junit", ".out"))
        runner_config.get("stderr", self.engine.create_artifact("junit", ".err"))

        self._cp_resource_files(self.runner_working_dir)

        self.runner = runner_class(runner_config, self.scenario, self.get_load(), self.log)
        self.runner.prepare()
        self.reader = JTLReader(self.kpi_file, self.log, self.err_jtl)
        if isinstance(self.engine.aggregator, ConsolidatingAggregator):
            self.engine.aggregator.add_underling(self.reader)

    def _verify_script(self):
        if not self.scenario.get("script"):
            if self.scenario.get("requests"):
                self.scenario["script"] = self.__tests_from_requests()
            else:
                raise RuntimeError("Nothing to test, no requests were provided in scenario")

    def _cp_resource_files(self, runner_working_dir):
        """
        :return:
        """
        script = self.scenario.get("script")

        if Scenario.SCRIPT in self.scenario:
            if os.path.isdir(script):
                shutil.copytree(script, runner_working_dir)
            else:
                os.makedirs(runner_working_dir)
                shutil.copy2(script, runner_working_dir)

    def detect_script_type(self, script_path):
        """
        checks if script is java or python
        if it's folder or single script
        :return:
        """
        if not isinstance(script_path, string_types) and not isinstance(script_path, text_type):
            raise RuntimeError("Nothing to test, no files were provided in scenario")
        test_files = []
        for dir_entry in os.walk(script_path):
            if dir_entry[2]:
                for test_file in dir_entry[2]:
                    if os.path.splitext(test_file)[1].lower() in SeleniumExecutor.SUPPORTED_TYPES:
                        test_files.append(test_file)

        if os.path.isdir(script_path):
            file_ext = os.path.splitext(test_files[0])[1].lower()
        else:
            file_ext = os.path.splitext(script_path)[1]

        if file_ext not in SeleniumExecutor.SUPPORTED_TYPES:
            raise RuntimeError("Supported tests types %s was not found" % SeleniumExecutor.SUPPORTED_TYPES)
        return file_ext

    def startup(self):
        """
        Start runner
        :return:
        """
        self.start_time = time.time()
        if self.virtual_display:
            msg = "Starting virtual display[%s]: %s"
            self.log.info(msg, self.virtual_display.size, self.virtual_display.new_display_var)
            self.virtual_display.start()
        self.runner.run_tests()

    def check(self):
        """
        check if test completed
        :return:
        """
        if self.widget:
            self.widget.update()

        if self.virtual_display:
            if not self.virtual_display.is_alive():
                self.log.info("Virtual display out: %s", self.virtual_display.stdout)
                self.log.warning("Virtual display err: %s", self.virtual_display.stderr)
                raise RuntimeError("Virtual display failed: %s" % self.virtual_display.return_code)

        return self.runner.is_finished()

    def shutdown(self):
        """
        shutdown test_runner
        :return:
        """
        try:
            self.runner.shutdown()
        finally:
            if self.virtual_display and self.virtual_display.is_alive():
                self.virtual_display.stop()

        if self.start_time:
            self.end_time = time.time()
            self.log.debug("Selenium tests ran for %s seconds", self.end_time - self.start_time)

    def post_process(self):
        if self.reader and not self.reader.read_records:
            raise RuntimeWarning("Empty results, most likely Selenium failed")

    def get_widget(self):
        if not self.widget:
            self.widget = SeleniumWidget(self.scenario.get("script"), self.runner.settings.get("stdout"))
        return self.widget

    def resource_files(self):
        if not self.scenario:
            self.scenario = self.get_scenario()

        if "script" not in self.scenario:
            return []

        script = self.scenario.get("script")
        script_type = self.detect_script_type(script)

        if script_type == ".py":
            runner_config = self.settings.get("selenium-tools").get("nose")
        elif script_type == ".jar" or script_type == ".java":
            runner_config = self.settings.get("selenium-tools").get("junit")
        else:
            raise ValueError("Unsupported script type: %s" % script_type)

        if self.runner_working_dir is None:
            self.runner_working_dir = self.engine.create_artifact(runner_config.get("working-dir", "classes"), "")

        self._cp_resource_files(self.runner_working_dir)

        return [os.path.basename(self.runner_working_dir)]

    def __tests_from_requests(self):
        filename = self.engine.create_artifact("test_requests", ".py")
        nose_test = SeleniumScriptBuilder(self.scenario, self.log)
        if self.virtual_display:
            nose_test.window_size=self.virtual_display.size
        nose_test.scenario = self.scenario
        nose_test.gen_test_case()
        nose_test.save(filename)
        return filename