Skip to content

Commit

Permalink
#389 Support More Complex CSS Selectors
Browse files Browse the repository at this point in the history
Test multiple selectors in PredicateBuilder.
Refactor PredicateBuilder.
  • Loading branch information
briemla committed Jan 21, 2020
1 parent 389e4aa commit cc40ec1
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 19 deletions.
39 changes: 28 additions & 11 deletions src/main/java/de/retest/web/selenium/css/PredicateBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,45 @@ public PredicateBuilder( final List<Transformer> selectors, final String origSel
}

public Optional<Predicate<Element>> 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<Element> combinePredicates() {
return predicates.stream().reduce( Predicate::and ).orElse( e -> true );
}

}
35 changes: 27 additions & 8 deletions src/test/java/de/retest/web/selenium/css/PredicateBuilderTest.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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<ILoggingEvent> logsList;

Expand Down Expand Up @@ -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<Transformer> transformers = singletonList( s -> matchingSelector );
final Optional<Predicate<Element>> predicate = buildPredicate( origSelector, transformers );
Expand All @@ -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<Transformer> transformers = singletonList( s -> matchingSelector );
final Optional<Predicate<Element>> predicate = buildPredicate( origSelector, transformers );

Expand All @@ -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<Transformer> transformers = asList( s -> someSelector, s -> otherSelector );
final Optional<Predicate<Element>> 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<Predicate<Element>> buildPredicate( final String origSelector,
final List<Transformer> transformers ) {
return new PredicateBuilder( transformers, origSelector ).build();
}

private void configureRemainingPart( final String remainingPart ) {
private Selector createSelectorWith( final String remainingPart, final Predicate<Element> 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;
}

}

0 comments on commit cc40ec1

Please sign in to comment.