Skip to content

Commit

Permalink
Experimental approach
Browse files Browse the repository at this point in the history
  • Loading branch information
vkepin committed Oct 17, 2024
1 parent d2c620d commit c1e967a
Show file tree
Hide file tree
Showing 15 changed files with 489 additions and 96 deletions.
1 change: 1 addition & 0 deletions vividus-engine/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ dependencies {
implementation(group: 'org.slf4j', name: 'slf4j-api')
implementation platform(group: 'org.springframework', name: 'spring-framework-bom', version: '6.1.13')
implementation(group: 'org.springframework', name: 'spring-beans')
implementation(group: 'org.springframework', name: 'spring-context')
implementation(group: 'com.google.guava', name: 'guava', version: '33.3.1-jre')
implementation(group: 'jakarta.inject', name: 'jakarta.inject-api', version: '2.0.1')
runtimeOnly(group: 'org.vividus', name: 'jbehave-spring', version: versions.jbehave)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.vividus.condition;

import java.util.Objects;
import java.util.Properties;
import java.util.stream.Stream;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public abstract class AbstractBooleanPropertyCondition implements Condition
{
private final String[] propertyNames;

protected AbstractBooleanPropertyCondition(String... propertyNames)
{
this.propertyNames = propertyNames;
}

@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata)
{
Properties properties = Objects.requireNonNull(context.getBeanFactory())
.getBean("properties", Properties.class);
return Stream.of(propertyNames).allMatch(p -> Boolean.parseBoolean(properties.getProperty(p)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.vividus.condition;

import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.junit.jupiter.params.provider.Arguments.arguments;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;

import java.util.Properties;
import java.util.stream.Stream;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

class AbstractBooleanPropertyConditionTests
{
private static final String TRUE = "true";
private static final String FALSE = "false";
private static final String FIRST_PROP = "prop1";
private static final String SECOND_PROP = "prop2";

static Stream<Arguments> propertyValues()
{
return Stream.of(
arguments(TRUE, TRUE, true),
arguments(FALSE, FALSE, false),
arguments(FALSE, TRUE, false),
arguments(TRUE, FALSE, false),
arguments(null, TRUE, false),
arguments(EMPTY, TRUE, false)
);
}

@ParameterizedTest
@MethodSource("propertyValues")
void testCondition(String firstPropValue, String secondPropValue, Boolean expected)
{
var beanFactory = mock(ConfigurableListableBeanFactory.class);
var metadata = mock(AnnotatedTypeMetadata.class);
var context = mock(ConditionContext.class);
var properties = mock(Properties.class);

when(context.getBeanFactory()).thenReturn(beanFactory);
when(beanFactory.getBean("properties", Properties.class)).thenReturn(properties);
when(properties.getProperty(FIRST_PROP)).thenReturn(firstPropValue);
when(properties.getProperty(SECOND_PROP)).thenReturn(secondPropValue);

var condition = new BooleanPropertyCondition();
Assertions.assertEquals(expected, condition.matches(context, metadata));
verifyNoInteractions(metadata);
}

static class BooleanPropertyCondition extends AbstractBooleanPropertyCondition
{
BooleanPropertyCondition()
{
super(FIRST_PROP, SECOND_PROP);
}
}
}
1 change: 1 addition & 0 deletions vividus-extension-selenium/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ configurations {
implementation(group: 'org.apache.commons', name: 'commons-lang3', version: '3.17.0')
implementation platform(group: 'org.springframework', name: 'spring-framework-bom', version: '6.1.13')
implementation(group: 'org.springframework', name: 'spring-core')
implementation(group: 'org.springframework', name: 'spring-context')

compileOnly(group: 'com.github.spotbugs', name: 'spotbugs-annotations', version: spotbugsVersion)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.vividus.ui.listener;

import org.springframework.stereotype.Component;
import org.vividus.condition.AbstractBooleanPropertyCondition;

@Component
public class AttachSourceCodePropertyCondition extends AbstractBooleanPropertyCondition
{
public AttachSourceCodePropertyCondition()
{
super("ui.publish-source-on-failure");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,26 @@

import com.google.common.eventbus.Subscribe;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.vividus.reporter.event.IAttachmentPublisher;
import org.vividus.selenium.IWebDriverProvider;
import org.vividus.softassert.event.AssertionFailedEvent;
import org.vividus.ui.ContextSourceCodeProvider;

@Conditional(AttachSourceCodePropertyCondition.class)
@Component
@Lazy(false)
public class SourceCodePublishingOnFailureListener
{
private final IWebDriverProvider webDriverProvider;
private final ContextSourceCodeProvider contextSourceCodeProvider;
private final IAttachmentPublisher attachmentPublisher;

private boolean publishSourceOnFailure;
private boolean publishShadowDomSourceOnFailure;
private String format;
@Autowired
private String sourceCodeAttachmentFormat;

public SourceCodePublishingOnFailureListener(IWebDriverProvider webDriverProvider,
ContextSourceCodeProvider contextSourceCodeProvider, IAttachmentPublisher attachmentPublisher)
Expand All @@ -46,44 +52,20 @@ public SourceCodePublishingOnFailureListener(IWebDriverProvider webDriverProvide
@Subscribe
public void onAssertionFailure(AssertionFailedEvent event)
{
if (publishSourceOnFailure && webDriverProvider.isWebDriverInitialized())
if (webDriverProvider.isWebDriverInitialized())
{
contextSourceCodeProvider.getSourceCode().forEach(this::publishSource);
if (publishShadowDomSourceOnFailure)
{
publishShadowDomSource();
}
}
}

private void publishSource(String title, String source)
{
attachmentPublisher.publishAttachment("/templates/source-code.ftl",
Map.of("sourceCode", source, "format", format), title);
Map.of("sourceCode", source, "format", sourceCodeAttachmentFormat), title);
}

private void publishShadowDomSource()
public void setSourceCodeAttachmentFormat(String sourceCodeAttachmentFormat)
{
Map<String, String> shadowDomSourceCode = contextSourceCodeProvider.getShadowDomSourceCode();
if (!shadowDomSourceCode.isEmpty())
{
attachmentPublisher.publishAttachment("/templates/shadow-code.ftl",
Map.of("shadowDomSources", shadowDomSourceCode), "Shadow DOM sources");
}
}

public void setPublishSourceOnFailure(boolean publishSourceOnFailure)
{
this.publishSourceOnFailure = publishSourceOnFailure;
}

public void setPublishShadowDomSourceOnFailure(boolean publishShadowDomSourceOnFailure)
{
this.publishShadowDomSourceOnFailure = publishShadowDomSourceOnFailure;
}

public void setFormat(String format)
{
this.format = format;
this.sourceCodeAttachmentFormat = sourceCodeAttachmentFormat;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd"
http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"
default-lazy-init="true" profile="web_selenium,mobile_app">

<context:component-scan base-package="org.vividus.ui.listener" />

<bean id="parentWebDriverFactory" class="org.vividus.selenium.GenericWebDriverFactory" abstract="true" />

<bean name="webDriverUrlProvider" class="org.vividus.selenium.StaticRemoteWebDriverUrlProvider">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.vividus.ui.listener;

import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.junit.jupiter.params.provider.Arguments.arguments;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;

import java.util.Properties;
import java.util.stream.Stream;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

class AttachSourceCodePropertyConditionTests
{
static Stream<Arguments> propertyValues()
{
return Stream.of(
arguments("true", true),
arguments("false", false),
arguments(null, false),
arguments(EMPTY, false)
);
}

@ParameterizedTest
@MethodSource("propertyValues")
void testCondition(String publishSource, Boolean expected)
{
var beanFactory = mock(ConfigurableListableBeanFactory.class);
var metadata = mock(AnnotatedTypeMetadata.class);
var context = mock(ConditionContext.class);
var properties = mock(Properties.class);

when(context.getBeanFactory()).thenReturn(beanFactory);
when(beanFactory.getBean("properties", Properties.class)).thenReturn(properties);
when(properties.getProperty("ui.publish-source-on-failure")).thenReturn(publishSource);

var condition = new AttachSourceCodePropertyCondition();
Assertions.assertEquals(expected, condition.matches(context, metadata));
verifyNoInteractions(metadata);
}
}
Loading

0 comments on commit c1e967a

Please sign in to comment.