Example #1
0
def console_writer_after_each_step(step):
    """
        Writes the step to the console after it was run

        :param Step step: the step to write to the console
    """
    if not isinstance(step.parent.parent, Feature):
        return

    color_func = get_color_func(step.state)
    line_jump_seq = get_line_jump_seq() * ((len(step.raw_text) + 3) if step.text else 1)
    output = "{}        {}{}".format(line_jump_seq, get_id_sentence_prefix(step, colorful.bold_cyan), color_func(step.sentence))

    if step.text:
        id_padding = get_id_padding(len(step.parent.steps))
        output += colorful.bold_white('\n            {}"""'.format(id_padding))
        output += colorful.cyan("".join(["\n                {}{}".format(id_padding, l) for l in step.raw_text]))
        output += colorful.bold_white('\n            {}"""'.format(id_padding))

    if step.state == step.State.FAILED:
        if world.config.with_traceback:
            output += "\n          {}{}".format(get_id_padding(len(step.parent.steps) - 2), "\n          ".join([colorful.red(l) for l in step.failure.traceback.split("\n")[:-2]]))
        output += "\n          {}{}: {}".format(get_id_padding(len(step.parent.steps) - 2), colorful.bold_red(step.failure.name), colorful.red(step.failure.reason))

    write(output)
Example #2
0
    def console_writer_before_each_feature(self, feature):
        """
            Writes feature header to the console

            :param Feature feature: the feature to write to the console
        """
        output = ""
        for tag in feature.tags:
            output += colorful.cyan(
                "@{0}{1}\n".format(tag.name, "({0})".format(tag.arg) if tag.arg else "")
            )

        leading = "\n    " if feature.description else ""

        output += "{0}{1}: {2}  # {3}{4}{5}".format(
            self.get_id_sentence_prefix(feature, colorful.bold_cyan),
            colorful.bold_white(feature.keyword),
            colorful.bold_white(feature.sentence),
            colorful.bold_black(feature.path),
            leading,
            colorful.white("\n    ".join(feature.description)),
        )

        if feature.background:
            output += "\n\n    {0}: {1}".format(
                colorful.bold_white(feature.background.keyword),
                colorful.bold_white(feature.background.sentence),
            )
            for step in feature.background.all_steps:
                output += "\n" + self._get_step_before_output(step, colorful.cyan)

        write(output)
Example #3
0
    def console_writer_before_each_feature(self, feature):
        """
            Writes feature header to the console

            :param Feature feature: the feature to write to the console
        """
        output = ""
        for tag in feature.tags:
            output += colorful.cyan(u"@{0}{1}\n".format(
                tag.name, "({0})".format(tag.arg) if tag.arg else ""))

        leading = "\n    " if feature.description else ""

        output += u"{0}{1}: {2}  # {3}{4}{5}".format(
            self.get_id_sentence_prefix(feature, colorful.bold_cyan),
            colorful.bold_white(feature.keyword),
            colorful.bold_white(feature.sentence),
            colorful.bold_black(feature.path), leading,
            colorful.white("\n    ".join(feature.description)))

        if feature.background:
            output += u"\n\n    {0}: {1}".format(
                colorful.bold_white(feature.background.keyword),
                colorful.bold_white(feature.background.sentence))
            for step in feature.background.all_steps:
                output += '\n' + self._get_step_before_output(
                    step, colorful.cyan)

        write(output)
Example #4
0
    def console_writer_after_each_step(self, step):
        """
            Writes the step to the console after it was run

            :param Step step: the step to write to the console
        """
        if not isinstance(step.parent.parent, Feature):
            return

        color_func = self.get_color_func(step.state)
        line_jump_seq = self.get_line_jump_seq() * (((len(step.raw_text) + 3) if step.text else 1) + (len(step.table) if step.table else 0))
        output = u"{0}        {1}{2}".format(line_jump_seq, self.get_id_sentence_prefix(step, colorful.bold_cyan), color_func(step.sentence))

        if step.text:
            id_padding = self.get_id_padding(len(step.parent.steps))
            output += colorful.bold_white(u'\n            {0}"""'.format(id_padding))
            output += colorful.cyan(u"".join(["\n                {0}{1}".format(id_padding, l) for l in step.raw_text]))
            output += colorful.bold_white(u'\n            {0}"""'.format(id_padding))

        if step.table:
            colored_pipe = colorful.bold_white("|")
            col_widths = self.get_table_col_widths(step.table)
            for row in step.table:
                output += u"\n          {0} {1} {0}".format(colored_pipe, (" {0} ").format(colored_pipe).join(
                    color_func(u"{1: <{0}}".format(col_widths[i], x)) for i, x in enumerate(row)
                ))

        if step.state == step.State.FAILED:
            if world.config.with_traceback:
                output += u"\n          {0}{1}".format(self.get_id_padding(len(step.parent.steps) - 2), "\n          ".join([colorful.red(l) for l in step.failure.traceback.split("\n")[:-2]]))
            output += u"\n          {0}{1}: {2}".format(self.get_id_padding(len(step.parent.steps) - 2), colorful.bold_red(step.failure.name), colorful.red(step.failure.reason))

        write(output)
Example #5
0
    def console_writer_after_each_feature(self, feature):  # pylint: disable=unused-argument
        """
            Writes a newline after each feature

            :param Feature feature: the feature which was ran.
        """
        write("")
Example #6
0
    def console_writer_after_each_feature(self, feature):  # pylint: disable=unused-argument
        """
            Writes a newline after each feature

            :param Feature feature: the feature which was ran.
        """
        write("")
Example #7
0
def console_writer_before_each_step(step):
    """
        Writes the step to the console before it is run

        :param Step step: the step to write to the console
    """
    global __LAST_PRECONDITION__
    if not isinstance(step.parent.parent, Feature):
        return

    if world.config.write_steps_once:
        return

    output = ""
    if step.as_precondition and __LAST_PRECONDITION__ != step.as_precondition:
        output += colorful.white("      As precondition from {}: {}\n".format(os.path.basename(step.as_precondition.path), step.as_precondition.sentence))
    elif not step.as_precondition and __LAST_PRECONDITION__:
        output += colorful.white("      From scenario\n")

    __LAST_PRECONDITION__ = step.as_precondition
    output += "\r        {}{}".format(get_id_sentence_prefix(step, colorful.bold_brown), colorful.bold_brown(step.sentence))

    if step.text:
        id_padding = get_id_padding(len(step.parent.steps))
        output += colorful.bold_white('\n            {}"""'.format(id_padding))
        output += colorful.cyan("".join(["\n                {}{}".format(id_padding, l) for l in step.raw_text]))
        output += colorful.bold_white('\n            {}"""'.format(id_padding))

    write(output)
Example #8
0
    def console_writer_before_each_step(self, step):
        """
            Writes the step to the console before it is run

            :param Step step: the step to write to the console
        """
        if not isinstance(step.parent.parent, Feature):
            return

        if world.config.write_steps_once:
            return

        output = ""
        if step.as_precondition and self.last_precondition != step.as_precondition:
            if step.as_background:
                output += colorful.italic_white(
                    "      As Background Precondition from {0}: {1}\n".format(
                        os.path.basename(step.as_precondition.path),
                        step.as_precondition.sentence,
                    )
                )
            else:
                output += colorful.italic_white(
                    "      As Precondition from {0}: {1}\n".format(
                        os.path.basename(step.as_precondition.path),
                        step.as_precondition.sentence,
                    )
                )
        elif step.as_background and self.last_background != step.as_background:
            output += colorful.italic_white(
                "      From Background: {0}\n".format(step.as_background.sentence)
            )
        elif (
            step.as_precondition
            and self.last_precondition
            and not step.as_background
            and self.last_background
        ):
            output += colorful.italic_white(
                "      From Precondition Scenario: {0}: {1}\n".format(
                    os.path.basename(step.as_precondition.path),
                    step.as_precondition.sentence,
                )
            )
        elif (not step.as_precondition and self.last_precondition) or (
            not step.as_background and self.last_background
        ):
            output += colorful.italic_white("      From Scenario\n")

        self.last_precondition = step.as_precondition
        self.last_background = step.as_background
        output += self._get_step_before_output(step)

        write(output)
Example #9
0
    def console_writer_after_each_step(self, step):
        """
            Writes the step to the console after it was run

            :param Step step: the step to write to the console
        """
        if not isinstance(step.parent.parent, Feature):
            return

        color_func = self.get_color_func(step.state)
        line_jump_seq = self.get_line_jump_seq() * (
            ((len(step.raw_text) + 3) if step.text else 1) +
            (len(step.table) if step.table else 0))
        output = u"{0}        {1}{2}".format(
            line_jump_seq, self.get_id_sentence_prefix(step,
                                                       colorful.bold_cyan),
            color_func(step.sentence))

        if step.text:
            id_padding = self.get_id_padding(len(step.parent.steps))
            output += colorful.bold_white(
                u'\n            {0}"""'.format(id_padding))
            output += colorful.cyan(u"".join([
                "\n                {0}{1}".format(id_padding, l)
                for l in step.raw_text
            ]))
            output += colorful.bold_white(
                u'\n            {0}"""'.format(id_padding))

        if step.table:
            colored_pipe = colorful.bold_white("|")
            col_widths = self.get_table_col_widths(step.table)
            for row in step.table:
                output += u"\n          {0} {1} {0}".format(
                    colored_pipe, (" {0} ").format(colored_pipe).join(
                        color_func(u"{1: <{0}}".format(col_widths[i], x))
                        for i, x in enumerate(row)))

        if step.state == step.State.FAILED:
            if world.config.with_traceback:
                output += u"\n          {0}{1}".format(
                    self.get_id_padding(len(step.parent.steps) - 2),
                    "\n          ".join([
                        colorful.red(l)
                        for l in step.failure.traceback.split("\n")[:-2]
                    ]))
            output += u"\n          {0}{1}: {2}".format(
                self.get_id_padding(len(step.parent.steps) - 2),
                colorful.bold_red(step.failure.name),
                colorful.red(step.failure.reason))

        write(output)
Example #10
0
    def console_writer_before_each_scenario(self, scenario):
        """
            Writes the scenario header to the console

            :param Scenario scenario: the scenario to write to the console
        """
        output = "\n"
        if isinstance(scenario.parent, ScenarioOutline):
            if world.config.write_steps_once:
                return

            id_prefix = self.get_id_sentence_prefix(
                scenario, colorful.bold_yellow, len(scenario.parent.scenarios))
            colored_pipe = colorful.bold_white("|")
            output = "        {0}{1} {2} {1}".format(
                id_prefix,
                colored_pipe,
                (" {0} ").format(colored_pipe).join(
                    str(
                        colorful.bold_yellow("{1: <{0}}".format(
                            scenario.parent.get_column_width(i), x)))
                    for i, x in enumerate(scenario.example.data)),
            )
        elif isinstance(scenario.parent, ScenarioLoop):
            if world.config.write_steps_once:
                return

            id_prefix = self.get_id_sentence_prefix(
                scenario, colorful.bold_yellow, len(scenario.parent.scenarios))
            colored_pipe = colorful.bold_white("|")
            output = "        {0}{1} {2: <18} {1}".format(
                id_prefix, colored_pipe,
                str(colorful.bold_yellow(scenario.iteration)))
        else:
            id_prefix = self.get_id_sentence_prefix(scenario,
                                                    colorful.bold_cyan)
            for tag in scenario.tags:
                if (
                        tag.name == "precondition" and world.config.expand
                        and world.config.show
                ):  # exceptional for show command when scenario steps expand and tag is a precondition -> comment it out
                    output += colorful.white("    # @{0}{1}\n".format(
                        tag.name, "({0})".format(tag.arg) if tag.arg else ""))
                else:
                    output += colorful.cyan("    @{0}{1}\n".format(
                        tag.name, "({0})".format(tag.arg) if tag.arg else ""))
            output += "    {0}{1}: {2}".format(
                id_prefix,
                colorful.bold_white(scenario.keyword),
                colorful.bold_white(scenario.sentence),
            )
        write(output)
Example #11
0
    def console_writer_before_each_step(self, step):
        """
            Writes the step to the console before it is run

            :param Step step: the step to write to the console
        """
        if not isinstance(step.parent.parent, Feature):
            return

        if world.config.write_steps_once:
            return

        output = ""
        if step.as_precondition and self.last_precondition != step.as_precondition:
            output += colorful.white(
                u"      As precondition from {0}: {1}\n".format(
                    os.path.basename(step.as_precondition.path),
                    step.as_precondition.sentence))
        elif not step.as_precondition and self.last_precondition:
            output += colorful.white(u"      From scenario\n")

        self.last_precondition = step.as_precondition
        output += u"\r        {0}{1}".format(
            self.get_id_sentence_prefix(step, colorful.bold_brown),
            colorful.bold_brown(step.sentence))

        if step.text:
            id_padding = self.get_id_padding(len(step.parent.steps))
            output += colorful.bold_white(
                u'\n            {0}"""'.format(id_padding))
            output += colorful.cyan(u"".join([
                "\n                {0}{1}".format(id_padding, l)
                for l in step.raw_text
            ]))
            output += colorful.bold_white(
                u'\n            {0}"""'.format(id_padding))

        if step.table:
            colored_pipe = colorful.bold_white("|")
            col_widths = self.get_table_col_widths(step.table)
            for row in step.table:
                output += u"\n          {0} {1} {0}".format(
                    colored_pipe, (" {0} ").format(colored_pipe).join(
                        colorful.bold_brown(u"{1: <{0}}".format(
                            col_widths[i], x)) for i, x in enumerate(row)))

        write(output)
Example #12
0
    def console_writer_before_each_step(self, step):
        """
            Writes the step to the console before it is run

            :param Step step: the step to write to the console
        """
        if not isinstance(step.parent.parent, Feature):
            return

        if world.config.write_steps_once:
            return

        output = ""
        if step.as_precondition and self.last_precondition != step.as_precondition:
            if step.as_background:
                output += colorful.italic_white(
                    "      As Background Precondition from {0}: {1}\n".format(
                        os.path.basename(step.as_precondition.path),
                        step.as_precondition.sentence,
                    ))
            else:
                output += colorful.italic_white(
                    "      As Precondition from {0}: {1}\n".format(
                        os.path.basename(step.as_precondition.path),
                        step.as_precondition.sentence,
                    ))
        elif step.as_background and self.last_background != step.as_background:
            output += colorful.italic_white(
                "      From Background: {0}\n".format(
                    step.as_background.sentence))
        elif (step.as_precondition and self.last_precondition
              and not step.as_background and self.last_background):
            output += colorful.italic_white(
                "      From Precondition Scenario: {0}: {1}\n".format(
                    os.path.basename(step.as_precondition.path),
                    step.as_precondition.sentence,
                ))
        elif (not step.as_precondition
              and self.last_precondition) or (not step.as_background
                                              and self.last_background):
            output += colorful.italic_white("      From Scenario\n")

        self.last_precondition = step.as_precondition
        self.last_background = step.as_background
        output += self._get_step_before_output(step)

        write(output)
Example #13
0
    def console_writer_after_each_scenario(self, scenario):
        """
            If the scenario is a ExampleScenario it will write the Examples header

            :param Scenario scenario: the scenario which was ran.
        """
        output = ""
        if isinstance(scenario, ScenarioOutline):
            output += u"\n    {0}:\n".format(colorful.bold_white(scenario.example_keyword))
            output += colorful.bold_white(u"        {0}| {1} |".format(
                self.get_id_padding(len(scenario.scenarios)),
                u" | ".join("{1: <{0}}".format(scenario.get_column_width(i), x) for i, x in enumerate(scenario.examples_header))
            ))
        elif isinstance(scenario, ScenarioLoop):
            output += u"\n    {0}: {1}".format(colorful.bold_white(scenario.iterations_keyword), colorful.cyan(scenario.iterations))
        elif isinstance(scenario.parent, ScenarioOutline):
            colored_pipe = colorful.bold_white("|")
            color_func = self.get_color_func(scenario.state)
            output += u"{0}        {1}{2} {3} {2}".format(
                self.get_line_jump_seq(),
                self.get_id_sentence_prefix(scenario, colorful.bold_cyan, len(scenario.parent.scenarios)),
                colored_pipe,
                (u" {0} ").format(colored_pipe).join(
                    color_func(u"{1: <{0}}".format(scenario.parent.get_column_width(i), x)) for i, x in enumerate(scenario.example.data)
                )
            )

            if scenario.state == Step.State.FAILED:
                failed_step = scenario.failed_step
                if world.config.with_traceback:
                    output += u"\n          {0}{1}".format(self.get_id_padding(len(scenario.parent.scenarios)), "\n          ".join([colorful.red(l) for l in failed_step.failure.traceback.split("\n")[:-2]]))
                output += u"\n          {0}{1}: {2}".format(self.get_id_padding(len(scenario.parent.scenarios)), colorful.bold_red(failed_step.failure.name), colorful.red(failed_step.failure.reason))
        elif isinstance(scenario.parent, ScenarioLoop):
            colored_pipe = colorful.bold_white("|")
            color_func = self.get_color_func(scenario.state)
            output += u"{0}        {1}{2} {3: <18} {2}".format(self.get_line_jump_seq(), self.get_id_sentence_prefix(scenario, colorful.bold_cyan, len(scenario.parent.scenarios)), colored_pipe, color_func(scenario.iteration))

            if scenario.state == Step.State.FAILED:
                failed_step = scenario.failed_step
                if world.config.with_traceback:
                    output += u"\n          {0}{1}".format(self.get_id_padding(len(scenario.parent.scenarios)), "\n          ".join([colorful.red(l) for l in failed_step.failure.traceback.split("\n")[:-2]]))
                output += u"\n          {0}{1}: {2}".format(self.get_id_padding(len(scenario.parent.scenarios)), colorful.bold_red(failed_step.failure.name), colorful.red(failed_step.failure.reason))

        if output:
            write(output)
Example #14
0
def console_writer_before_each_feature(feature):
    """
        Writes feature header to the console

        :param Feature feature: the feature to write to the console
    """
    output = ""
    for tag in feature.tags:
        output += colorful.cyan("@{}{}\n".format(tag.name, "({})".format(tag.arg) if tag.arg else ""))

    leading = "\n    " if feature.description else ""

    output += "{}{}: {}{}{}".format(
        get_id_sentence_prefix(feature, colorful.bold_cyan),
        colorful.bold_white(feature.keyword),
        colorful.bold_white(feature.sentence),
        leading,
        colorful.white("\n    ".join(feature.description))
    )
    write(output)
Example #15
0
    def console_writer_before_each_step(self, step):
        """
            Writes the step to the console before it is run

            :param Step step: the step to write to the console
        """
        if not isinstance(step.parent.parent, Feature):
            return

        if world.config.write_steps_once:
            return

        output = ""
        if step.as_precondition and self.last_precondition != step.as_precondition:
            output += colorful.white(u"      As precondition from {0}: {1}\n".format(os.path.basename(step.as_precondition.path), step.as_precondition.sentence))
        elif not step.as_precondition and self.last_precondition:
            output += colorful.white(u"      From scenario\n")

        self.last_precondition = step.as_precondition
        output += u"\r        {0}{1}".format(self.get_id_sentence_prefix(step, colorful.bold_brown), colorful.bold_brown(step.sentence))

        if step.text:
            id_padding = self.get_id_padding(len(step.parent.steps))
            output += colorful.bold_white(u'\n            {0}"""'.format(id_padding))
            output += colorful.cyan(u"".join(["\n                {0}{1}".format(id_padding, l) for l in step.raw_text]))
            output += colorful.bold_white(u'\n            {0}"""'.format(id_padding))

        if step.table:
            colored_pipe = colorful.bold_white("|")
            col_widths = self.get_table_col_widths(step.table)
            for row in step.table:
                output += u"\n          {0} {1} {0}".format(colored_pipe, (" {0} ").format(colored_pipe).join(
                    colorful.bold_brown(u"{1: <{0}}".format(col_widths[i], x)) for i, x in enumerate(row)
                ))

        write(output)
Example #16
0
    def console_writer_before_each_scenario(self, scenario):
        """
            Writes the scenario header to the console

            :param Scenario scenario: the scenario to write to the console
        """
        output = "\n"
        if isinstance(scenario.parent, ScenarioOutline):
            if world.config.write_steps_once:
                return

            id_prefix = self.get_id_sentence_prefix(scenario, colorful.bold_brown, len(scenario.parent.scenarios))
            colored_pipe = colorful.bold_white("|")
            output = u"        {0}{1} {2} {1}".format(
                id_prefix,
                colored_pipe,
                (u" {0} ").format(colored_pipe).join(
                    colorful.bold_brown(u"{1: <{0}}".format(scenario.parent.get_column_width(i), x)) for i, x in enumerate(scenario.example.data)
                )
            )
        elif isinstance(scenario.parent, ScenarioLoop):
            if world.config.write_steps_once:
                return

            id_prefix = self.get_id_sentence_prefix(scenario, colorful.bold_brown, len(scenario.parent.scenarios))
            colored_pipe = colorful.bold_white("|")
            output = u"        {0}{1} {2: <18} {1}".format(id_prefix, colored_pipe, colorful.bold_brown(scenario.iteration))
        else:
            id_prefix = self.get_id_sentence_prefix(scenario, colorful.bold_cyan)
            for tag in scenario.tags:
                if tag.name == "precondition" and world.config.expand and world.config.show:  # exceptional for show command when scenario steps expand and tag is a precondition -> comment it out
                    output += colorful.white(u"    # @{0}{1}\n".format(tag.name, "({0})".format(tag.arg) if tag.arg else ""))
                else:
                    output += colorful.cyan(u"    @{0}{1}\n".format(tag.name, u"({0})".format(tag.arg) if tag.arg else ""))
            output += u"    {0}{1}: {2}".format(id_prefix, colorful.bold_white(scenario.keyword), colorful.bold_white(scenario.sentence))
        write(output)
Example #17
0
    def console_write(self, features, marker):
        """
            Writes the endreport for all features

            :param list features: all features
        """
        stats = {
            "features": {
                "amount": 0,
                "passed": 0,
                "failed": 0,
                "skipped": 0,
                "untested": 0,
                "pending": 0,
            },
            "scenarios": {
                "amount": 0,
                "passed": 0,
                "failed": 0,
                "skipped": 0,
                "untested": 0,
                "pending": 0,
            },
            "steps": {
                "amount": 0,
                "passed": 0,
                "failed": 0,
                "skipped": 0,
                "untested": 0,
                "pending": 0,
            },
        }
        pending_steps = []
        duration = timedelta()
        for feature in features:
            if not feature.has_to_run(world.config.scenarios):
                continue
            stats["features"]["amount"] += 1
            stats["features"][feature.state] += 1

            if feature.state in [Step.State.PASSED, Step.State.FAILED]:
                duration += feature.duration

            for scenario in feature.all_scenarios:
                if not scenario.has_to_run(world.config.scenarios):
                    continue

                if isinstance(scenario, ScenarioOutline):  # skip ScenarioOutlines
                    continue
                if isinstance(scenario, ScenarioLoop):  # skip ScenarioLoop
                    continue

                stats["scenarios"]["amount"] += 1
                stats["scenarios"][scenario.state] += 1
                for step in scenario.steps:
                    stats["steps"]["amount"] += 1
                    stats["steps"][step.state] += 1

                    if step.state == Step.State.PENDING:
                        pending_steps.append(step)

        colored_closing_paren = colorful.bold_white(")")
        colored_comma = colorful.bold_white(", ")
        passed_word = colorful.bold_green("{0} passed")
        failed_word = colorful.bold_red("{0} failed")
        skipped_word = colorful.cyan("{0} skipped")
        pending_word = colorful.bold_yellow("{0} pending")

        output = colorful.bold_white(
            "{0} features (".format(stats["features"]["amount"])
        )
        output += passed_word.format(stats["features"]["passed"])
        if stats["features"]["failed"]:
            output += colored_comma + failed_word.format(stats["features"]["failed"])
        if stats["features"]["skipped"]:
            output += colored_comma + skipped_word.format(stats["features"]["skipped"])
        if stats["features"]["pending"]:
            output += colored_comma + pending_word.format(stats["features"]["pending"])
        output += colored_closing_paren

        output += "\n"
        output += colorful.bold_white(
            "{} scenarios (".format(stats["scenarios"]["amount"])
        )
        output += passed_word.format(stats["scenarios"]["passed"])
        if stats["scenarios"]["failed"]:
            output += colored_comma + failed_word.format(stats["scenarios"]["failed"])
        if stats["scenarios"]["skipped"]:
            output += colored_comma + skipped_word.format(stats["scenarios"]["skipped"])
        if stats["scenarios"]["pending"]:
            output += colored_comma + pending_word.format(stats["scenarios"]["pending"])
        output += colored_closing_paren

        output += "\n"
        output += colorful.bold_white("{} steps (".format(stats["steps"]["amount"]))
        output += passed_word.format(stats["steps"]["passed"])
        if stats["steps"]["failed"]:
            output += colored_comma + failed_word.format(stats["steps"]["failed"])
        if stats["steps"]["skipped"]:
            output += colored_comma + skipped_word.format(stats["steps"]["skipped"])
        if stats["steps"]["pending"]:
            output += colored_comma + pending_word.format(stats["steps"]["pending"])
        output += colored_closing_paren

        if pending_steps:
            sr = StepRegistry()
            pending_step_implementations = make_unique_obj_list(
                pending_steps, lambda x: x.definition_func
            )
            output += colorful.white(
                "\nYou have {0} pending step implementation{1} affecting {2} step{3}:\n  {4}\n\nNote: this could be the reason for some failing subsequent steps".format(
                    len(pending_step_implementations),
                    "s" if len(pending_step_implementations) is not 1 else "",
                    len(pending_steps),
                    "s" if len(pending_steps) is not 1 else "",
                    "\n  ".join(
                        [
                            "-  '{0}' @ {1}".format(
                                sr.get_pattern(s.definition_func),
                                get_func_code(s.definition_func).co_filename,
                            )
                            for s in pending_step_implementations
                        ]
                    ),
                )
            )

        output += "\n"

        if world.config.wip:
            if stats["scenarios"]["passed"] > 0:
                output += colorful.red(
                    "\nThe --wip switch was used, so I didn't expect anything to pass. These scenarios passed:\n"
                )

                has_passed_scenarios = False
                for feature in features:
                    passed_scenarios = list(
                        filter(
                            lambda s: s.state == Step.State.PASSED,
                            feature.all_scenarios,
                        )
                    )
                    for scenario in passed_scenarios:
                        output += colorful.red(
                            "\n - {}: {}".format(feature.path, scenario.sentence)
                        )
                        has_passed_scenarios = True

                if has_passed_scenarios:
                    output += "\n"
            else:
                output += colorful.green(
                    "\nThe --wip switch was used, so the failures were expected. All is good.\n"
                )

        output += colorful.cyan(
            "Run {0} finished within {1}".format(
                marker, humanize.naturaldelta(duration)
            )
        )

        write(output)
Example #18
0
def console_write_after_all(features, marker):
    """
        Writes the endreport for all features

        :param list features: all features
    """
    stats = {
        "features": {"amount": 0, "passed": 0, "failed": 0, "skipped": 0, "untested": 0},
        "scenarios": {"amount": 0, "passed": 0, "failed": 0, "skipped": 0, "untested": 0},
        "steps": {"amount": 0, "passed": 0, "failed": 0, "skipped": 0, "untested": 0},
    }
    duration = timedelta()
    for feature in features:
        stats["features"]["amount"] += 1
        stats["features"][feature.state] += 1

        if feature.state in [Step.State.PASSED, Step.State.FAILED]:
            duration += feature.duration

        for scenario in feature.all_scenarios:
            if isinstance(scenario, ScenarioOutline):  # skip ScenarioOutlines
                continue

            stats["scenarios"]["amount"] += 1
            stats["scenarios"][scenario.state] += 1
            for step in scenario.steps:
                stats["steps"]["amount"] += 1
                stats["steps"][step.state] += 1

    colored_closing_paren = colorful.bold_white(")")
    colored_comma = colorful.bold_white(", ")
    passed_word = colorful.bold_green("{} passed")
    failed_word = colorful.bold_red("{} failed")
    skipped_word = colorful.cyan("{} skipped")

    output = colorful.bold_white("{} features (".format(stats["features"]["amount"]))
    output += passed_word.format(stats["features"]["passed"])
    if stats["features"]["failed"]:
        output += colored_comma + failed_word.format(stats["features"]["failed"])
    if stats["features"]["skipped"]:
        output += colored_comma + skipped_word.format(stats["features"]["skipped"])
    output += colored_closing_paren

    output += "\n"
    output += colorful.bold_white("{} scenarios (".format(stats["scenarios"]["amount"]))
    output += passed_word.format(stats["scenarios"]["passed"])
    if stats["scenarios"]["failed"]:
        output += colored_comma + failed_word.format(stats["scenarios"]["failed"])
    if stats["scenarios"]["skipped"]:
        output += colored_comma + skipped_word.format(stats["scenarios"]["skipped"])
    output += colored_closing_paren

    output += "\n"
    output += colorful.bold_white("{} steps (".format(stats["steps"]["amount"]))
    output += passed_word.format(stats["steps"]["passed"])
    if stats["steps"]["failed"]:
        output += colored_comma + failed_word.format(stats["steps"]["failed"])
    if stats["steps"]["skipped"]:
        output += colored_comma + skipped_word.format(stats["steps"]["skipped"])
    output += colored_closing_paren

    output += "\n"
    output += colorful.cyan("Run {} finished within {}:{} minutes".format(marker, int(duration.total_seconds()) / 60, duration.total_seconds() % 60.0))

    write(output)
Example #19
0
    def console_write(self, features, marker):
        """
            Writes the endreport for all features

            :param list features: all features
        """
        stats = {
            "features": {
                "amount": 0,
                "passed": 0,
                "failed": 0,
                "skipped": 0,
                "untested": 0,
                "pending": 0
            },
            "scenarios": {
                "amount": 0,
                "passed": 0,
                "failed": 0,
                "skipped": 0,
                "untested": 0,
                "pending": 0
            },
            "steps": {
                "amount": 0,
                "passed": 0,
                "failed": 0,
                "skipped": 0,
                "untested": 0,
                "pending": 0
            },
        }
        pending_steps = []
        duration = timedelta()
        for feature in features:
            if not feature.has_to_run(world.config.scenarios,
                                      world.config.feature_tags,
                                      world.config.scenario_tags):
                continue
            stats["features"]["amount"] += 1
            stats["features"][feature.state] += 1

            if feature.state in [Step.State.PASSED, Step.State.FAILED]:
                duration += feature.duration

            for scenario in feature.all_scenarios:
                if not scenario.has_to_run(world.config.scenarios,
                                           world.config.feature_tags,
                                           world.config.scenario_tags):
                    continue

                if isinstance(scenario,
                              ScenarioOutline):  # skip ScenarioOutlines
                    continue
                if isinstance(scenario, ScenarioLoop):  # skip ScenarioLoop
                    continue

                stats["scenarios"]["amount"] += 1
                stats["scenarios"][scenario.state] += 1
                for step in scenario.steps:
                    stats["steps"]["amount"] += 1
                    stats["steps"][step.state] += 1

                    if step.state == Step.State.PENDING:
                        pending_steps.append(step)

        colored_closing_paren = colorful.bold_white(")")
        colored_comma = colorful.bold_white(", ")
        passed_word = colorful.bold_green("{0} passed")
        failed_word = colorful.bold_red("{0} failed")
        skipped_word = colorful.cyan("{0} skipped")
        pending_word = colorful.bold_brown("{0} pending")

        output = colorful.bold_white("{0} features (".format(
            stats["features"]["amount"]))
        output += passed_word.format(stats["features"]["passed"])
        if stats["features"]["failed"]:
            output += colored_comma + failed_word.format(
                stats["features"]["failed"])
        if stats["features"]["skipped"]:
            output += colored_comma + skipped_word.format(
                stats["features"]["skipped"])
        if stats["features"]["pending"]:
            output += colored_comma + pending_word.format(
                stats["features"]["pending"])
        output += colored_closing_paren

        output += "\n"
        output += colorful.bold_white("{} scenarios (".format(
            stats["scenarios"]["amount"]))
        output += passed_word.format(stats["scenarios"]["passed"])
        if stats["scenarios"]["failed"]:
            output += colored_comma + failed_word.format(
                stats["scenarios"]["failed"])
        if stats["scenarios"]["skipped"]:
            output += colored_comma + skipped_word.format(
                stats["scenarios"]["skipped"])
        if stats["scenarios"]["pending"]:
            output += colored_comma + pending_word.format(
                stats["scenarios"]["pending"])
        output += colored_closing_paren

        output += "\n"
        output += colorful.bold_white("{} steps (".format(
            stats["steps"]["amount"]))
        output += passed_word.format(stats["steps"]["passed"])
        if stats["steps"]["failed"]:
            output += colored_comma + failed_word.format(
                stats["steps"]["failed"])
        if stats["steps"]["skipped"]:
            output += colored_comma + skipped_word.format(
                stats["steps"]["skipped"])
        if stats["steps"]["pending"]:
            output += colored_comma + pending_word.format(
                stats["steps"]["pending"])
        output += colored_closing_paren

        if pending_steps:
            sr = StepRegistry()
            pending_step_implementations = make_unique_obj_list(
                pending_steps, lambda x: x.definition_func)
            output += colorful.white(
                "\nYou have {0} pending step implementation{1} affecting {2} step{3}:\n  {4}\n\nNote: this could be the reason for some failing subsequent steps"
                .format(
                    len(pending_step_implementations),
                    "s" if len(pending_step_implementations) is not 1 else "",
                    len(pending_steps),
                    "s" if len(pending_steps) is not 1 else "", "\n  ".join([
                        "-  '{0}' @ {1}".format(
                            sr.get_pattern(s.definition_func),
                            get_func_code(s.definition_func).co_filename)
                        for s in pending_step_implementations
                    ])))

        output += "\n"
        output += colorful.cyan(
            "Run {0} finished within {1}:{2} minutes".format(
                marker,
                int(duration.total_seconds()) / 60,
                duration.total_seconds() % 60.0))

        write(output)
Example #20
0
    def console_write(self, features, marker):
        """
            Writes the endreport for all features

            :param list features: all features
        """
        stats = {
            "features": {"amount": 0, "passed": 0, "failed": 0, "skipped": 0, "untested": 0, "pending": 0},
            "scenarios": {"amount": 0, "passed": 0, "failed": 0, "skipped": 0, "untested": 0, "pending": 0},
            "steps": {"amount": 0, "passed": 0, "failed": 0, "skipped": 0, "untested": 0, "pending": 0},
        }
        pending_steps = []
        duration = timedelta()
        for feature in features:
            if not feature.has_to_run(world.config.scenarios, world.config.feature_tags, world.config.scenario_tags):
                continue
            stats["features"]["amount"] += 1
            stats["features"][feature.state] += 1

            if feature.state in [Step.State.PASSED, Step.State.FAILED]:
                duration += feature.duration

            for scenario in feature.all_scenarios:
                if not scenario.has_to_run(world.config.scenarios, world.config.feature_tags, world.config.scenario_tags):
                    continue

                if isinstance(scenario, ScenarioOutline):  # skip ScenarioOutlines
                    continue
                if isinstance(scenario, ScenarioLoop):  # skip ScenarioLoop
                    continue

                stats["scenarios"]["amount"] += 1
                stats["scenarios"][scenario.state] += 1
                for step in scenario.steps:
                    stats["steps"]["amount"] += 1
                    stats["steps"][step.state] += 1

                    if step.state == Step.State.PENDING:
                        pending_steps.append(step)

        colored_closing_paren = colorful.bold_white(")")
        colored_comma = colorful.bold_white(", ")
        passed_word = colorful.bold_green("{0} passed")
        failed_word = colorful.bold_red("{0} failed")
        skipped_word = colorful.cyan("{0} skipped")
        pending_word = colorful.bold_brown("{0} pending")

        output = colorful.bold_white("{0} features (".format(stats["features"]["amount"]))
        output += passed_word.format(stats["features"]["passed"])
        if stats["features"]["failed"]:
            output += colored_comma + failed_word.format(stats["features"]["failed"])
        if stats["features"]["skipped"]:
            output += colored_comma + skipped_word.format(stats["features"]["skipped"])
        if stats["features"]["pending"]:
            output += colored_comma + pending_word.format(stats["features"]["pending"])
        output += colored_closing_paren

        output += "\n"
        output += colorful.bold_white("{} scenarios (".format(stats["scenarios"]["amount"]))
        output += passed_word.format(stats["scenarios"]["passed"])
        if stats["scenarios"]["failed"]:
            output += colored_comma + failed_word.format(stats["scenarios"]["failed"])
        if stats["scenarios"]["skipped"]:
            output += colored_comma + skipped_word.format(stats["scenarios"]["skipped"])
        if stats["scenarios"]["pending"]:
            output += colored_comma + pending_word.format(stats["scenarios"]["pending"])
        output += colored_closing_paren

        output += "\n"
        output += colorful.bold_white("{} steps (".format(stats["steps"]["amount"]))
        output += passed_word.format(stats["steps"]["passed"])
        if stats["steps"]["failed"]:
            output += colored_comma + failed_word.format(stats["steps"]["failed"])
        if stats["steps"]["skipped"]:
            output += colored_comma + skipped_word.format(stats["steps"]["skipped"])
        if stats["steps"]["pending"]:
            output += colored_comma + pending_word.format(stats["steps"]["pending"])
        output += colored_closing_paren

        if pending_steps:
            sr = StepRegistry()
            pending_step_implementations = make_unique_obj_list(pending_steps, lambda x: x.definition_func)
            output += colorful.white("\nYou have {0} pending step implementation{1} affecting {2} step{3}:\n  {4}\n\nNote: this could be the reason for some failing subsequent steps".format(
                len(pending_step_implementations),
                "s" if len(pending_step_implementations) is not 1 else "",
                len(pending_steps),
                "s" if len(pending_steps) is not 1 else "",
                "\n  ".join(["-  '{0}' @ {1}".format(sr.get_pattern(s.definition_func), get_func_code(s.definition_func).co_filename) for s in pending_step_implementations])
            ))

        output += "\n"
        output += colorful.cyan("Run {0} finished within {1}:{2} minutes".format(marker, int(duration.total_seconds()) / 60, duration.total_seconds() % 60.0))

        write(output)
Example #21
0
    def console_writer_after_each_step(self, step):
        """
            Writes the step to the console after it was run

            :param Step step: the step to write to the console
        """
        if not isinstance(step.parent.parent, Feature):
            return

        color_func = self.get_color_func(step.state)
        line_jump_seq = self.get_line_jump_seq() * (
            ((len(step.raw_text) + 3) if step.text else 1) +
            (len(step.table) + 1 if step.table_header else 0))
        output = u'{0}        '.format(line_jump_seq)

        if isinstance(step.parent, ScenarioOutline):
            # Highlight ScenarioOutline placeholders e.g. '<method>'
            output += (u''.join(
                str(
                    colorful.white(item) if (
                        self._placeholder_regex.search(item)
                        and item.strip('<>') in step.parent.examples_header
                    ) else color_func(item))
                for item in self._placeholder_regex.split(step.sentence)))
        else:
            output += u"{0}{1}".format(
                self.get_id_sentence_prefix(step, colorful.bold_cyan),
                color_func(step.sentence))

        if step.text:
            id_padding = self.get_id_padding(len(step.parent.steps))
            output += colorful.bold_white(
                u'\n            {0}"""'.format(id_padding))
            output += colorful.cyan(u"".join([
                "\n                {0}{1}".format(id_padding, l)
                for l in step.raw_text
            ]))
            output += colorful.bold_white(
                u'\n            {0}"""'.format(id_padding))

        if step.table_header:
            colored_pipe = colorful.bold_white("|")
            col_widths = self.get_table_col_widths([step.table_header] +
                                                   step.table_data)

            # output table header
            output += u"\n          {0} {1} {0}".format(
                colored_pipe, (" {0} ").format(colored_pipe).join(
                    str(colorful.white(u"{1: <{0}}".format(col_widths[i], x)))
                    for i, x in enumerate(step.table_header)))

            # output table data
            for row in step.table_data:
                output += u"\n          {0} {1} {0}".format(
                    colored_pipe, (" {0} ").format(colored_pipe).join(
                        str(color_func(u"{1: <{0}}".format(col_widths[i], x)))
                        for i, x in enumerate(row)))

        if step.state == step.State.FAILED:
            if world.config.with_traceback:
                output += u"\n          {0}{1}".format(
                    self.get_id_padding(len(step.parent.steps) - 2),
                    "\n          ".join([
                        str(colorful.red(l))
                        for l in step.failure.traceback.split("\n")[:-2]
                    ]))
            output += u"\n          {0}{1}: {2}".format(
                self.get_id_padding(len(step.parent.steps) - 2),
                colorful.bold_red(step.failure.name),
                colorful.red(step.failure.reason))

        write(output)
Example #22
0
    def console_writer_after_each_scenario(self, scenario):
        """
            If the scenario is a ExampleScenario it will write the Examples header

            :param Scenario scenario: the scenario which was ran.
        """
        output = ""
        if isinstance(scenario, ScenarioOutline):
            output += u"\n    {0}:\n".format(
                colorful.bold_white(scenario.example_keyword))
            output += colorful.bold_white(u"        {0}| {1} |".format(
                self.get_id_padding(len(scenario.scenarios), offset=2),
                u" | ".join("{1: <{0}}".format(scenario.get_column_width(i), x)
                            for i, x in enumerate(scenario.examples_header))))
        elif isinstance(scenario, ScenarioLoop):
            output += u"\n    {0}: {1}".format(
                colorful.bold_white(scenario.iterations_keyword),
                colorful.cyan(scenario.iterations))
        elif isinstance(scenario.parent, ScenarioOutline):
            colored_pipe = colorful.bold_white("|")
            color_func = self.get_color_func(scenario.state)
            output += u"{0}        {1}{2} {3} {2}".format(
                self.get_line_jump_seq(),
                self.get_id_sentence_prefix(scenario, colorful.bold_cyan,
                                            len(scenario.parent.scenarios)),
                colored_pipe, (u" {0} ").format(colored_pipe).join(
                    str(
                        color_func(u"{1: <{0}}".format(
                            scenario.parent.get_column_width(i), x)))
                    for i, x in enumerate(scenario.example.data)))

            if scenario.state == Step.State.FAILED:
                failed_step = scenario.failed_step
                if world.config.with_traceback:
                    output += u"\n          {0}{1}".format(
                        self.get_id_padding(len(scenario.parent.scenarios)),
                        "\n          ".join([
                            str(colorful.red(l)) for l in
                            failed_step.failure.traceback.split("\n")[:-2]
                        ]))
                output += u"\n          {0}{1}: {2}".format(
                    self.get_id_padding(len(scenario.parent.scenarios)),
                    colorful.bold_red(failed_step.failure.name),
                    colorful.red(failed_step.failure.reason))
        elif isinstance(scenario.parent, ScenarioLoop):
            colored_pipe = colorful.bold_white("|")
            color_func = self.get_color_func(scenario.state)
            output += u"{0}        {1}{2} {3: <18} {2}".format(
                self.get_line_jump_seq(),
                self.get_id_sentence_prefix(scenario, colorful.bold_cyan,
                                            len(scenario.parent.scenarios)),
                colored_pipe, str(color_func(scenario.iteration)))

            if scenario.state == Step.State.FAILED:
                failed_step = scenario.failed_step
                if world.config.with_traceback:
                    output += u"\n          {0}{1}".format(
                        self.get_id_padding(len(scenario.parent.scenarios)),
                        "\n          ".join([
                            str(colorful.red(l)) for l in
                            failed_step.failure.traceback.split("\n")[:-2]
                        ]))
                output += u"\n          {0}{1}: {2}".format(
                    self.get_id_padding(len(scenario.parent.scenarios)),
                    colorful.bold_red(failed_step.failure.name),
                    colorful.red(failed_step.failure.reason))

        if output:
            write(output)
Example #23
0
    def console_writer_after_each_step(self, step):
        """
            Writes the step to the console after it was run

            :param Step step: the step to write to the console
        """
        if not isinstance(step.parent.parent, Feature):
            return

        color_func = self.get_color_func(step.state)
        line_jump_seq = self.get_line_jump_seq() * (
            ((len(step.raw_text) + 3) if step.text else 1)
            + (len(step.table) + 1 if step.table_header else 0)
        )
        output = "{0}        ".format(line_jump_seq)

        if isinstance(step.parent, ScenarioOutline):
            # Highlight ScenarioOutline placeholders e.g. '<method>'
            output += "".join(
                str(
                    colorful.white(item)
                    if (
                        self._placeholder_regex.search(item)
                        and item.strip("<>") in step.parent.examples_header
                    )
                    else color_func(item)
                )
                for item in self._placeholder_regex.split(step.sentence)
            )
        else:
            output += "{0}{1}".format(
                self.get_id_sentence_prefix(step, colorful.bold_cyan),
                color_func(step.sentence),
            )

        if step.text:
            id_padding = self.get_id_padding(len(step.parent.steps))
            output += colorful.bold_white('\n            {0}"""'.format(id_padding))
            output += colorful.cyan(
                "".join(
                    [
                        "\n                {0}{1}".format(id_padding, l)
                        for l in step.raw_text
                    ]
                )
            )
            output += colorful.bold_white('\n            {0}"""'.format(id_padding))

        if step.table_header:
            colored_pipe = colorful.bold_white("|")
            col_widths = self.get_table_col_widths(
                [step.table_header] + step.table_data
            )

            # output table header
            output += "\n          {0} {1} {0}".format(
                colored_pipe,
                (" {0} ")
                .format(colored_pipe)
                .join(
                    str(colorful.white("{1: <{0}}".format(col_widths[i], x)))
                    for i, x in enumerate(step.table_header)
                ),
            )

            # output table data
            for row in step.table_data:
                output += "\n          {0} {1} {0}".format(
                    colored_pipe,
                    (" {0} ")
                    .format(colored_pipe)
                    .join(
                        str(color_func("{1: <{0}}".format(col_widths[i], x)))
                        for i, x in enumerate(row)
                    ),
                )

        if step.state == step.State.FAILED:
            if world.config.with_traceback:
                output += "\n          {0}{1}".format(
                    self.get_id_padding(len(step.parent.steps) - 2),
                    "\n          ".join(
                        [
                            str(colorful.red(l))
                            for l in step.failure.traceback.split("\n")[:-2]
                        ]
                    ),
                )
            output += "\n          {0}{1}: {2}".format(
                self.get_id_padding(len(step.parent.steps) - 2),
                colorful.bold_red(step.failure.name),
                colorful.red(step.failure.reason),
            )

        write(output)
Example #24
0
    def console_write(self, features, marker):
        """
            Writes the endreport for all features

            :param list features: all features
        """
        stats = {
            "features": {
                "amount": 0,
                "passed": 0,
                "failed": 0,
                "skipped": 0,
                "untested": 0,
                "pending": 0,
            },
            "scenarios": {
                "amount": 0,
                "passed": 0,
                "failed": 0,
                "skipped": 0,
                "untested": 0,
                "pending": 0,
            },
            "steps": {
                "amount": 0,
                "passed": 0,
                "failed": 0,
                "skipped": 0,
                "untested": 0,
                "pending": 0,
            },
        }
        pending_steps = []
        duration = timedelta()
        for feature in features:
            if not feature.has_to_run(world.config.scenarios):
                continue
            stats["features"]["amount"] += 1
            stats["features"][feature.state] += 1

            if feature.state in [Step.State.PASSED, Step.State.FAILED]:
                duration += feature.duration

            for scenario in feature.all_scenarios:
                if not scenario.has_to_run(world.config.scenarios):
                    continue

                if isinstance(scenario,
                              ScenarioOutline):  # skip ScenarioOutlines
                    continue
                if isinstance(scenario, ScenarioLoop):  # skip ScenarioLoop
                    continue

                stats["scenarios"]["amount"] += 1
                stats["scenarios"][scenario.state] += 1
                for step in scenario.steps:
                    stats["steps"]["amount"] += 1
                    stats["steps"][step.state] += 1

                    if step.state == Step.State.PENDING:
                        pending_steps.append(step)

        colored_closing_paren = colorful.bold_white(")")
        colored_comma = colorful.bold_white(", ")
        passed_word = colorful.bold_green("{0} passed")
        failed_word = colorful.bold_red("{0} failed")
        skipped_word = colorful.cyan("{0} skipped")
        pending_word = colorful.bold_yellow("{0} pending")

        output = colorful.bold_white("{0} features (".format(
            stats["features"]["amount"]))
        output += passed_word.format(stats["features"]["passed"])
        if stats["features"]["failed"]:
            output += colored_comma + failed_word.format(
                stats["features"]["failed"])
        if stats["features"]["skipped"]:
            output += colored_comma + skipped_word.format(
                stats["features"]["skipped"])
        if stats["features"]["pending"]:
            output += colored_comma + pending_word.format(
                stats["features"]["pending"])
        output += colored_closing_paren

        output += "\n"
        output += colorful.bold_white("{} scenarios (".format(
            stats["scenarios"]["amount"]))
        output += passed_word.format(stats["scenarios"]["passed"])
        if stats["scenarios"]["failed"]:
            output += colored_comma + failed_word.format(
                stats["scenarios"]["failed"])
        if stats["scenarios"]["skipped"]:
            output += colored_comma + skipped_word.format(
                stats["scenarios"]["skipped"])
        if stats["scenarios"]["pending"]:
            output += colored_comma + pending_word.format(
                stats["scenarios"]["pending"])
        output += colored_closing_paren

        output += "\n"
        output += colorful.bold_white("{} steps (".format(
            stats["steps"]["amount"]))
        output += passed_word.format(stats["steps"]["passed"])
        if stats["steps"]["failed"]:
            output += colored_comma + failed_word.format(
                stats["steps"]["failed"])
        if stats["steps"]["skipped"]:
            output += colored_comma + skipped_word.format(
                stats["steps"]["skipped"])
        if stats["steps"]["pending"]:
            output += colored_comma + pending_word.format(
                stats["steps"]["pending"])
        output += colored_closing_paren

        if pending_steps:
            sr = StepRegistry()
            pending_step_implementations = make_unique_obj_list(
                pending_steps, lambda x: x.definition_func)
            output += colorful.white(
                "\nYou have {0} pending step implementation{1} affecting {2} step{3}:\n  {4}\n\nNote: this could be the reason for some failing subsequent steps"
                .format(
                    len(pending_step_implementations),
                    "s" if len(pending_step_implementations) is not 1 else "",
                    len(pending_steps),
                    "s" if len(pending_steps) is not 1 else "",
                    "\n  ".join([
                        "-  '{0}' @ {1}".format(
                            sr.get_pattern(s.definition_func),
                            get_func_code(s.definition_func).co_filename,
                        ) for s in pending_step_implementations
                    ]),
                ))

        output += "\n"

        if world.config.wip:
            if stats["scenarios"]["passed"] > 0:
                output += colorful.red(
                    "\nThe --wip switch was used, so I didn't expect anything to pass. These scenarios passed:\n"
                )

                has_passed_scenarios = False
                for feature in features:
                    passed_scenarios = list(
                        filter(
                            lambda s: s.state == Step.State.PASSED,
                            feature.all_scenarios,
                        ))
                    for scenario in passed_scenarios:
                        output += colorful.red("\n - {}: {}".format(
                            feature.path, scenario.sentence))
                        has_passed_scenarios = True

                if has_passed_scenarios:
                    output += "\n"
            else:
                output += colorful.green(
                    "\nThe --wip switch was used, so the failures were expected. All is good.\n"
                )

        output += colorful.cyan("Run {0} finished within {1}".format(
            marker, humanize.naturaldelta(duration)))

        write(output)