From 17b385233cc32bea37fa411665246c6df041e80b Mon Sep 17 00:00:00 2001 From: Uladzislau Arlouski Date: Wed, 27 Sep 2023 12:21:18 +0300 Subject: [PATCH] [plugin-web-app-to-rest-api] Add jump links verifications --- .../steps/integration/ResourceCheckSteps.java | 30 +++++++++++++++---- .../model/ResourceValidationError.java | 4 ++- .../integration/ResourceCheckStepsTests.java | 27 ++++++++++++++--- .../src/main/resources/known-issues.json | 7 +++++ .../integration/ResourceCheckSteps.story | 4 +-- 5 files changed, 59 insertions(+), 13 deletions(-) diff --git a/vividus-plugin-web-app-to-rest-api/src/main/java/org/vividus/steps/integration/ResourceCheckSteps.java b/vividus-plugin-web-app-to-rest-api/src/main/java/org/vividus/steps/integration/ResourceCheckSteps.java index a22bc78ae6..a00fa49c11 100644 --- a/vividus-plugin-web-app-to-rest-api/src/main/java/org/vividus/steps/integration/ResourceCheckSteps.java +++ b/vividus-plugin-web-app-to-rest-api/src/main/java/org/vividus/steps/integration/ResourceCheckSteps.java @@ -135,9 +135,7 @@ private void validateResources(Stream resourceValidat private WebPageResourceValidation validate(WebPageResourceValidation r) { - return CheckStatus.BROKEN == r.getCheckStatus() || CheckStatus.FILTERED == r.getCheckStatus() - ? r - : resourceValidator.perform(r); + return r.getCheckStatus() != null ? r : resourceValidator.perform(r); } private Stream createResourceValidations(Collection elements, @@ -150,7 +148,7 @@ private Stream createResourceValidations(Collection { resourceValidator.accept(rv); - if (rv.getCheckStatus() != CheckStatus.BROKEN && !isSchemaAllowed(rv.getUriOrError().getLeft()) + if (rv.getCheckStatus() == null && !isSchemaAllowed(rv.getUriOrError().getLeft()) || excludeHrefsPattern.matcher(rv.toString()).matches()) { rv.setCheckStatus(CheckStatus.FILTERED); @@ -177,7 +175,22 @@ private Optional parseElement(Element element) try { Pair elementUri = Pair.of(resolveUri(elementUriAsString), null); - return Optional.of(new WebPageResourceValidation(elementUri, elementCssSelector)); + WebPageResourceValidation validation = new WebPageResourceValidation(elementUri, elementCssSelector); + + if (isJumpLink(elementUriAsString)) + { + String fragment = elementUri.getLeft().getFragment(); + Element target = element.root().getElementById(fragment); + if (target == null) + { + return Optional.of(ResourceValidationError.MISSING_JUMPLINK_TARGET + .onAssertion(softAssert::recordFailedAssertion, elementCssSelector, fragment) + .createValidation(null, elementCssSelector, fragment)); + } + validation.setCheckStatus(CheckStatus.PASSED); + } + + return Optional.of(validation); } catch (URISyntaxException e) { @@ -188,6 +201,11 @@ private Optional parseElement(Element element) } } + private static boolean isJumpLink(String url) + { + return url.startsWith(URL_FRAGMENT) && url.length() > 1; + } + private static boolean isSchemaAllowed(URI uri) { return Optional.ofNullable(uri.getScheme()).map(ALLOWED_SCHEMES::contains).orElse(false); @@ -198,7 +216,7 @@ private static String getElementUri(Element element) String href = element.attr(HREF_ATTR); if (!href.isEmpty()) { - if (URL_FRAGMENT.equals(href)) + if (URL_FRAGMENT.equals(href) || isJumpLink(href)) { return href; } diff --git a/vividus-plugin-web-app-to-rest-api/src/main/java/org/vividus/validator/model/ResourceValidationError.java b/vividus-plugin-web-app-to-rest-api/src/main/java/org/vividus/validator/model/ResourceValidationError.java index 592c858ae9..1501019c17 100644 --- a/vividus-plugin-web-app-to-rest-api/src/main/java/org/vividus/validator/model/ResourceValidationError.java +++ b/vividus-plugin-web-app-to-rest-api/src/main/java/org/vividus/validator/model/ResourceValidationError.java @@ -29,7 +29,9 @@ public enum ResourceValidationError EMPTY_HREF_SRC("Element doesn't contain href/src attributes", "Element by selector %s doesn't contain href/src attributes"), INVALID_HREF_SRC("Element has href/src attribute with invalid URL: %s", - "Element by selector %s has href/src attribute with invalid URL: %s"); + "Element by selector %s has href/src attribute with invalid URL: %s"), + MISSING_JUMPLINK_TARGET("Jump link points to missing element with %s id", + "Jump link by selector %s points to missing element with %s id"); private final String errorFormat; private final String assertionFormat; diff --git a/vividus-plugin-web-app-to-rest-api/src/test/java/org/vividus/steps/integration/ResourceCheckStepsTests.java b/vividus-plugin-web-app-to-rest-api/src/test/java/org/vividus/steps/integration/ResourceCheckStepsTests.java index 1baa62c65f..577e6ebbf2 100644 --- a/vividus-plugin-web-app-to-rest-api/src/test/java/org/vividus/steps/integration/ResourceCheckStepsTests.java +++ b/vividus-plugin-web-app-to-rest-api/src/test/java/org/vividus/steps/integration/ResourceCheckStepsTests.java @@ -110,6 +110,10 @@ class ResourceCheckStepsTests private static final String SELECTOR_QUERY_1 = "#query-params-one"; private static final URI VIVIDUS_QUERY_URI_2 = URI.create("https://vividus.org/products?name=smetanka"); private static final String SELECTOR_QUERY_2 = "#query-params-two"; + private static final URI EXTERNAL_SECTION_LINK = URI.create("https://external.page/other#section"); + private static final String EXTERNAL_SECTION_LINK_SELECTOR = "#external-section"; + private static final String SECTION_SELECTOR = "#section"; + private static final String JUMP_LINK_SELECTOR = "#jump-link"; private static final String INVALID_URL = "https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|" + "Google+Sans:400,500,700|Google+Sans+Text:400&lang=en"; @@ -142,6 +146,9 @@ class ResourceCheckStepsTests