From cc40ec1ea22a858849dd836eb29b21e32c959cc3 Mon Sep 17 00:00:00 2001 From: Lars Briem Date: Sun, 24 Nov 2019 18:12:01 +0100 Subject: [PATCH] #389 Support More Complex CSS Selectors Test multiple selectors in PredicateBuilder. Refactor PredicateBuilder. --- .../web/selenium/css/PredicateBuilder.java | 39 +++++++++++++------ .../selenium/css/PredicateBuilderTest.java | 35 +++++++++++++---- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/src/main/java/de/retest/web/selenium/css/PredicateBuilder.java b/src/main/java/de/retest/web/selenium/css/PredicateBuilder.java index 7d6716de9..3f4768728 100644 --- a/src/main/java/de/retest/web/selenium/css/PredicateBuilder.java +++ b/src/main/java/de/retest/web/selenium/css/PredicateBuilder.java @@ -25,28 +25,45 @@ public PredicateBuilder( final List selectors, final String origSel } public Optional> build() { - String selector = origSelector; + final String remainingSelector = parse( origSelector ); + + if ( isPartAvailable( remainingSelector ) ) { + logUnkownSelector( remainingSelector ); + return Optional.empty(); + + } + return Optional.of( combinePredicates() ); + } + + private String parse( final String selector ) { + String remainingSelector = selector; boolean matched = true; - while ( !selector.isEmpty() && matched ) { + while ( isPartAvailable( remainingSelector ) && matched ) { matched = false; for ( final Transformer function : selectors ) { - final Selector cssSelector = function.transform( selector ); + final Selector cssSelector = function.transform( remainingSelector ); if ( cssSelector.matches() ) { predicates.add( cssSelector.predicate() ); - selector = cssSelector.remainingSelector(); + remainingSelector = cssSelector.remainingSelector(); matched = cssSelector.matches(); } } } + return remainingSelector; + } - if ( !selector.isEmpty() ) { - logger.warn( - "Unbreakable tests are not implemented for all CSS selectors. Please report your chosen selector ('{}') at https://github.com/retest/recheck-web/issues.", - selector ); - return Optional.empty(); + private boolean isPartAvailable( final String selector ) { + return !selector.isEmpty(); + } - } - return Optional.of( predicates.stream().reduce( Predicate::and ).orElse( e -> true ) ); + private void logUnkownSelector( final String selector ) { + logger.warn( + "Unbreakable tests are not implemented for all CSS selectors. Please report your chosen selector ('{}') at https://github.com/retest/recheck-web/issues.", + selector ); + } + + private Predicate combinePredicates() { + return predicates.stream().reduce( Predicate::and ).orElse( e -> true ); } } diff --git a/src/test/java/de/retest/web/selenium/css/PredicateBuilderTest.java b/src/test/java/de/retest/web/selenium/css/PredicateBuilderTest.java index 7b5c49307..305755b3f 100644 --- a/src/test/java/de/retest/web/selenium/css/PredicateBuilderTest.java +++ b/src/test/java/de/retest/web/selenium/css/PredicateBuilderTest.java @@ -1,9 +1,12 @@ package de.retest.web.selenium.css; +import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.List; @@ -25,12 +28,11 @@ @ExtendWith( MockitoExtension.class ) public class PredicateBuilderTest { - private static final String CSS_SELECTOR_NOT_SUPPORTED = "Unbreakable tests are not implemented for all CSS selectors."; + private static final String CSS_SELECTOR_NOT_SUPPORTED = + "Unbreakable tests are not implemented for all CSS selectors."; @Mock private Element element; @Mock - private Selector matchingSelector; - @Mock private Element otherElement; private List logsList; @@ -68,7 +70,7 @@ void parse_unknown_selector() throws Exception { @Test void parse_selector_with_unknown_part() throws Exception { final String remainingPart = "remaining"; - configureRemainingPart( remainingPart ); + final Selector matchingSelector = createSelectorWith( remainingPart, e -> false ); final String origSelector = "abc"; final List transformers = singletonList( s -> matchingSelector ); final Optional> predicate = buildPredicate( origSelector, transformers ); @@ -81,9 +83,9 @@ void parse_selector_with_unknown_part() throws Exception { @Test void parse_matching_selector() throws Exception { - final String remainingPart = ""; - configureRemainingPart( remainingPart ); final String origSelector = "abc"; + final String remainingPart = ""; + final Selector matchingSelector = createSelectorWith( remainingPart, element::equals ); final List transformers = singletonList( s -> matchingSelector ); final Optional> predicate = buildPredicate( origSelector, transformers ); @@ -93,15 +95,32 @@ void parse_matching_selector() throws Exception { } + @Test + void parse_multiple_matching_selectors() throws Exception { + final String origSelector = "abc"; + final Selector someSelector = createSelectorWith( "def", e -> true ); + final Selector otherSelector = createSelectorWith( "", e -> false ); + final List transformers = asList( s -> someSelector, s -> otherSelector ); + final Optional> predicate = buildPredicate( origSelector, transformers ); + + assertAll( () -> assertThat( predicate.map( p -> p.test( element ) ) ).hasValue( false ), + () -> assertThat( logsList ).isEmpty() ); + verify( someSelector ).predicate(); + verify( otherSelector ).predicate(); + + } + private Optional> buildPredicate( final String origSelector, final List transformers ) { return new PredicateBuilder( transformers, origSelector ).build(); } - private void configureRemainingPart( final String remainingPart ) { + private Selector createSelectorWith( final String remainingPart, final Predicate predicate ) { + final Selector matchingSelector = mock( Selector.class ); when( matchingSelector.matches() ).thenReturn( true, false ); when( matchingSelector.remainingSelector() ).thenReturn( remainingPart ); - when( matchingSelector.predicate() ).thenReturn( element::equals ); + when( matchingSelector.predicate() ).thenReturn( predicate ); + return matchingSelector; } }