class CypressScenariosIndexer implements ScenariosIndexer {

    @Override
    public List<ExecutedScenario> getExecutedScenarios(File parentFolder, Run run, Long projectId) {
        List<ExecutedScenario> executedScenarios = new ArrayList<>();

        String cucumberReportsFolderPath = technologySettingService.getSettingValue(projectId, CypressSettings.CUCUMBER_REPORTS_FOLDER_PATHS).orElse("");
        Optional<File> cucumberFolder = fileProcessorService.getMatchingDirectory(parentFolder, cucumberReportsFolderPath);

        if (!cucumberFolder.isPresent()) {
            return executedScenarios;
        }

        String cucumberSuffixValue = technologySettingService.getSettingValue(projectId, CypressSettings.CUCUMBER_FILE_NAME_SUFFIX_VALUE).orElse("");
        String cucumberReportFileNameSuffix = String.format(".%s.json", cucumberSuffixValue);
        File[] cucumberFolderContent = cucumberFolder.get().listFiles();
        List<File> cucumberReportFiles = Arrays.stream(cucumberFolderContent)
                .filter(File::isFile)
                .filter(file -> file.getName().endsWith(cucumberReportFileNameSuffix))
                .collect(Collectors.toList());

        if (cucumberReportFiles.isEmpty()) {
            return executedScenarios;
        }

        String stepDefinitionsFolderPath = technologySettingService.getSettingValue(projectId, CypressSettings.STEP_DEFINITIONS_FOLDER_PATH).orElse("");
        Optional<File> stepDefinitionFolder = fileProcessorService.getMatchingDirectory(parentFolder, stepDefinitionsFolderPath);
        final List<File> stepDefinitionFiles = stepDefinitionFolder
                .map(File::listFiles)
                .map(files -> {
                    String stepDefinitionsSuffixValue = technologySettingService.getSettingValue(projectId, CypressSettings.STEP_DEFINITIONS_FILE_NAME_SUFFIX_VALUE).orElse("");
                    String stepDefinitionFileNameSuffix = String.format(".%s.json", stepDefinitionsSuffixValue);
                    return Arrays.stream(files)
                            .filter(File::isFile)
                            .filter(file -> file.getName().endsWith(stepDefinitionFileNameSuffix))
                            .collect(Collectors.toList());
                })
                .orElse(new ArrayList<>());

        executedScenarios = cucumberReportFiles.stream()
                .map(file -> Pair.of(file, getStepDefinitionsFile(file, stepDefinitionFiles)))
                .map(pair ->
                        Pair.of(
                                cucumberScenariosIndexer.getCucumberFeaturesFromReport(pair.getFirst()),
                                pair.getSecond().isPresent() ? cucumberScenariosIndexer.getCucumberStepDefinitions(pair.getSecond().get()) : new ArrayList<String>()
                        )
                )
                .map(pair -> executedScenarioExtractorService.extractExecutedScenarios(pair.getFirst(), pair.getSecond(), run.getJobUrl()))
                .flatMap(Collection::stream)
                .collect(Collectors.toList());

        String mediaPath = technologySettingService.getSettingValue(projectId, CypressSettings.MEDIA_FILE_PATH).orElse("");
        List<CypressMedia> medias = fileProcessorService.getMappedObjectListFromFile(parentFolder, mediaPath, CypressMedia.class);

        executedScenarios = executedScenarios.stream()
                .map(scenario -> {
                    Optional<Pair<Optional<String>, String>> mediaUrls = getSnapshotAndVideoUrls(scenario, medias);
                    mediaUrls.ifPresent(pair -> {
                        pair.getFirst().ifPresent(scenario::setScreenshotUrl);
                        scenario.setVideoUrl(pair.getSecond());
                    });
                    return scenario;
                })
                .collect(Collectors.toList());

        return executedScenarios;
    }

}