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.")
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
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
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")
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()