def validate(self, step_data):
        """ Receives the step-data as input and validates through the
            ``action`` key in the given dictionary

            Returns a validated instance of the step
        """
        errors = {}
        # Title/Action validation must be done prior to the actual step
        # validation
        if "title" not in step_data:
            step_title = "<unknown>"
            raise exceptions.ValidationError(
                {step_title: "``title`` attribute is not provided on step."})
        step_title = step_data.pop("title")
        errors[step_title] = []
        if "action" not in step_data:
            errors[step_title].append(
                "``action`` is attribute not provided on step.")
            raise exceptions.ValidationError(errors)
        action = step_data.pop("action")

        try:
            step_cls = steps.registered_steps.get_registered_step(action)
        except KeyError:
            raise exceptions.ValidationError(f"{step_title}'s ``step_cls`` "
                                             "not found.")
        # TODO: Since the sub-steps aren't initialized with a screenshots path,
        # their screenshots CAN NOT BE SAVED at the moment!
        step_cls = step_cls(step_data=step_data, title=step_title)
        if not step_cls.is_valid():
            errors[step_title] = step_cls.errors
            raise exceptions.ValidationError(errors)

        return step_cls
 def validate(self, value):
     """ Validates that the value has a smaller length than self.length """
     try:
         len(value)
     except TypeError:
         raise exceptions.ValidationError("Value has no attribute len()")
     if len(value) > self.length:
         raise exceptions.ValidationError(
             f"Length greater than {self.length}")
    def validate(self, value):
        """ Validates that the value is either a resolved variable or of the
            given ``required_type``
        """
        placeholders = steps.resolvers.VariableResolver.find_variables(value)
        no_placeholders = placeholders is None or len(placeholders) != 1

        if self.required_type is not None:
            if no_placeholders and not isinstance(value, self.required_type):
                raise exceptions.ValidationError(
                    f"The `{value}` is not a resolved variable, and is not of "
                    "the required type either.")
        else:
            if no_placeholders and value is None:
                raise exceptions.ValidationError(
                    f"The `{value}` is not a resolved variable, and is not of "
                    "the required type either.")
Beispiel #4
0
    def is_valid(self):
        """ Validates the ``yaml_data`` attribute using the ``validate``
            method

            Either return ``True`` or raises a ValidationError with the
            issues
        """
        is_valid = self.validate()
        if not is_valid:
            raise exceptions.ValidationError(self.errors)
        return True
Beispiel #5
0
    def is_valid(self, raise_exception=False):
        """ Calls the validate method and sets the ``_validated_data`` property
            with the returned data
        """
        assert self.step_data is not None, (
            "There is no data to validate. The ``step_data`` parameter must "
            "be passed into the step for it to get validated.")

        if self.validate():
            return True
        else:
            if raise_exception:
                raise exceptions.ValidationError(self.errors)
            return False
Beispiel #6
0
    def validate(self, value):
        """ Validates the given ``value`` based on the active attributes on the
            class
        """
        errors = []
        for validator in self.validators:
            if not validator.is_valid(value):
                error = validator.error
                if isinstance(error, list):
                    errors += error
                else:
                    errors.append(error)

        if errors:
            self._errors = errors
            raise exceptions.ValidationError(self._errors)
        self._value = value
        self._errors = []

        return value
 def validate(self, value):
     """ Validates that the value is an existing file path """
     if not os.path.exists(value):
         raise exceptions.ValidationError(
             f"The `{value}` file path does not exist.")
 def validate(self, value):
     """ Validates that the value is in the ``options`` array """
     if value not in self.options:
         raise exceptions.ValidationError(
             f"Value is not one of {self.options}.")
 def validate(self, value):
     """ Validates that the value is an instance of ``self.field_type`` """
     if not isinstance(value, self.field_type):
         raise exceptions.ValidationError(
             f"Value is not an instance of {self.field_type.__name__}.")
 def validate(self, value):
     """ Validates that the value isn't Null """
     if value is None:
         raise exceptions.ValidationError(
             "Value is required but not provided")
Beispiel #11
0
    def __init__(self,
                 yaml_file=None,
                 driver_class=webdriver.Chrome,
                 driver_options=None,
                 driver_executable_path='chromedriver',
                 save_screenshots=False,
                 parse_template=False,
                 template_context=None,
                 driver=None):
        """ Creates a new instance of the SeleniumYAML parser and validates the
            provided yaml as well as initializes the driver (if not provided)

            ``yaml_file``, if specified, must be an open File-like object or a
            string path to a YAML file with valid YAML containing the steps
            that will be used for creating the automation; one of either
            ``yaml_file`` or ``yaml_string`` must be provided

            ``driver_class``, if specified, must be a valid Selenium webdriver
            class (either a driver class in selenium.webdriver or a subclass of
            the same) - defaults to selenium.webdriver.Chrome

            ``driver_options``, if specified, must be a set of Selenium options
            compatible with the active ``driver_class``

            ``driver_executable_path``, if specified, must be the path to the
            driver for the active ``driver_class``

            ``save_screenshots``, if specified, is used to take screenshots of
            each step after it's executed or if it runs into an exception

            ``parse_template``, if True, parses the given YAML File as a Jinja2
            template prior to parsing it through the YAMLParser

            ``template_context`` is passed to Jinja2's Template.render method
            as context if ``parse_template`` is True

            ``driver``, if present, is used as the driver class for the engine;
            this is used in case you want the bot to act on an already running
            driver
        """
        # TODO: Improve cases if the path to the file doesn't exist since at
        # the moment it just returns ""
        assert yaml_file, "YAML not provided"
        if isinstance(yaml_file, str) and os.path.exists(yaml_file):
            with open(yaml_file, encoding="UTF-8") as inf:
                yaml_file = inf.read()

        # These are set as class attributes so that they can be passed to any
        # bots connected via `run_bot` steps
        self.parse_template = parse_template
        self.template_context = template_context
        if parse_template:
            template_context = template_context or {}
            template = Template(yaml_file)
            yaml_file = template.render(template_context)

        parser = YAMLParser(yaml_file)
        if parser.is_valid():
            self.steps = parser.validated_steps
            self.title = parser.bot_title
            self.exception_steps = parser.validated_exception_steps
        else:
            raise exceptions.ValidationError(parser.errors)

        self.save_screenshots = save_screenshots
        self.performance_context = OrderedDict()

        if isinstance(driver, webdriver.remote.webdriver.WebDriver):
            self.driver = driver
        else:
            self.driver_class = driver_class
            self.driver_options = driver_options
            self.driver_executable_path = driver_executable_path
            self.driver = self.__initialize_driver()