Ok, I will check. Can you send a sample zip copy of a working story with google login or Yahoo login so that I can fix issue and send it to you in couple of days
On Thu, Nov 1, 2018, 7:52 PM Gajendra Sahu <[email protected] wrote: > Hi, > > I am using *JBehave Core 4.3.5* with *JBehave Web Selenium 3.6-beta-2*. > > After debugging I found out that the code never goes inside if > (!future.isDone()) > {So it never initialized duration. Not sure what I am doing wrong. I am > only running 1 story at a time. > > public void waitUntilAllDoneOrFailed(RunContext context) { > if ( runningStories.values().isEmpty() ) { > return; > } > boolean allDone = false; > boolean started = false; > while (!allDone || !started) { > allDone = true; > for (RunningStory runningStory : runningStories.values()) { > if ( runningStory.isStarted() ){ > started = true; > Story story = runningStory.getStory(); > Future<ThrowableStory> future = runningStory.getFuture(); > *if **(!future.isDone()) {* > allDone = false; > StoryDuration duration = runningStory.getDuration(); > runningStory.updateDuration(); > if (duration.timedOut()) { > embedderMonitor.storyTimeout(story, duration); > context.cancelStory(story, duration); > future.cancel(true); > if (embedderControls.failOnStoryTimeout()) { > throw new StoryExecutionFailed(story.getPath(), > new StoryTimedOut(duration)); > } > continue; > } > } else { > try { > ThrowableStory throwableStory = future.get(); > Throwable throwable = throwableStory.getThrowable(); > if (throwable != null) { > context.addFailure(story.getPath(), throwable); > if (!embedderControls.ignoreFailureInStories()) { > continue; > } > } > } catch (Throwable e) { > context.addFailure(story.getPath(), e); > if (!embedderControls.ignoreFailureInStories()) { > continue; > } > } > } > } else { > started = false; > allDone = false; > } > } > tickTock(); > } > writeStoryDurations(runningStories.values()); > } > > > public StoriesRunner() { > setBrowser(); > try { > if (lifeCycleSteps instanceof PerStoriesWebDriverSteps) { > JUnitReportingRunner.recommendedControls(configuredEmbedder()); > configuredEmbedder().useExecutorService(new > DirectExecutorService(){ > }.create( > configuredEmbedder() > .embedderControls() > .doBatch(false) > .doGenerateViewAfterStories(true) > .doIgnoreFailureInStories(false) > .doIgnoreFailureInView(false) > .doSkip(false) > .doVerboseFailures(false) > .doVerboseFiltering(false) > .useStoryTimeouts("3000") > )); > /* Required to run stories with annotated meta filters */ > > configuredEmbedder().useMetaFilters(Arrays.asList(getListOfStoriesToRun().split(","))); > } > } catch (IOException e) { > e.printStackTrace(); > } > } > > @Override > public Configuration configuration() { > Class<? extends Embeddable> embeddableClass = this.getClass(); > return new SeleniumConfiguration() > .useWebDriverProvider(driverProvider) > .useSeleniumContext(context) > .useStepCollector(stepCollector) > /*.useStepMonitor(new SeleniumStepMonitor(contextView, context, > new SilentStepMonitor()))*/ > .useStoryLoader(new LoadFromClasspath(embeddableClass)) > .useParameterConverters(new > ParameterConverters().addConverters(new ParameterConverters.DateConverter(new > SimpleDateFormat("yyyy-MM-dd")))) > .useStoryReporterBuilder(new StoryReporterBuilder() > .withCodeLocation(codeLocationFromClass(embeddableClass)) > .withDefaultFormats() > .withFormats(Format.STATS, > Format.CONSOLE, > Format.XML, > Format.TXT, > /*Format.HTML,*/ > screenShootingFormat) > .withFailureTrace(true) > ); > } > > private String getListOfStoriesToRun() throws IOException { > if (System.getProperty("stories") == null) { > //System.out.print(System.getProperty("story")); > return readProperties.getStories(); > } else { > return System.getProperty("stories"); > } > } > > @Override > protected List<String> storyPaths() { > return new > StoryFinder().findPaths(CodeLocations.codeLocationFromPath("./src/main/resources"), > "**/*.story", ""); > } > > > On Thu, Nov 1, 2018 at 8:02 AM Maganti Suryanarayana murthy < > [email protected]> wrote: > >> Latest jbehave jars solved the problem >> >> On Wed, Oct 31, 2018, 10:45 PM Gajendra Sahu <[email protected] >> wrote: >> >>> Any updates on this? I am facing the same issue. >>> >>> Running using JunitStories and the storyDuration.props has durations 0. >>> >>> On Friday, 23 February 2018 11:58:17 UTC-6, mauro.talevi wrote: >>>> >>>> Please package all this in a downloadable zip that can be opened and >>>> run. Don't forget a readme with tool versions etc >>>> >>>> On 23 Feb 2018, at 18:32, Maganti Suryanarayana murthy < >>>> [email protected]> wrote: >>>> >>>> Hi Mauro Talevi, >>>> >>>> I have used gradle as a build file and please find the code base that i >>>> am using. I am pasing build.gradle file and apptechJbehaveStories.java >>>> >>>> Build.gradle: >>>> >>>> def buildNumber = System.getProperty('buildNumber') ?: '0' >>>> def buildVersion = '1.0.0-' + buildNumber >>>> >>>> version = buildVersion >>>> >>>> apply plugin: 'groovy' >>>> apply plugin: 'java' >>>> apply plugin: 'maven' >>>> >>>> >>>> repositories { >>>> mavenCentral() >>>> } >>>> >>>> configurations { >>>> jbehave >>>> } >>>> >>>> dependencies { >>>> testCompile group: 'junit', name: 'junit', version: '4.11' >>>> compile(group: 'org.jbehave.web', name: 'jbehave-web-selenium', >>>> version:'4.0-beta-1') { >>>> exclude(module: 'selenium-remote-control') >>>> exclude(module: 'selenium-java') >>>> exclude(module: 'jbehave-core') >>>> } >>>> compile 'org.springframework:spring-webmvc:5.0.2.RELEASE' >>>> compile 'org.jbehave.site:jbehave-site-resources:3.3.1' >>>> compile 'org.jbehave:jbehave-spring:4.1.3' >>>> compile 'org.jbehave:jbehave-core:4.1.3' >>>> compile 'log4j:log4j:1.2.16' >>>> compile group: 'org.seleniumhq.selenium', name: 'selenium-java', >>>> version: '3.7.1' >>>> compile group: 'commons-collections', name: 'commons-collections', >>>> version: '3.2.1' >>>> testCompile group: 'org.jbehave', name: 'jbehave-core', version: >>>> '4.1.3' >>>> compile 'org.jbehave.site:jbehave-site-resources:3.3.1:@zip' >>>> } >>>> >>>> /** userDefined task to copy the srories from /src/main/stories into >>>> build/classes/test/stories*/ >>>> task copyStories(type: Copy) { >>>> from 'src/main/resources' into "${buildDir}/classes/test" >>>> from 'src/main/stories' into "${buildDir}/classes/test/stories" >>>> } >>>> >>>> >>>> task copyJbehaveStyle(type: Copy) { >>>> from(zipTree(jarPath("jbehave-core"))) { >>>> include "style/*" >>>> } >>>> into("${buildDir}/classes/jbehave/view") >>>> } >>>> >>>> task copyJbehaveUtilities(type: Copy) { >>>> from(zipTree(jarPath("jbehave-site-resources"))) { >>>> include "js/**/*" >>>> include "style/**/*" >>>> include "images/*" >>>> } >>>> into("${buildDir}/classes/jbehave/view") >>>> } >>>> >>>> def jarPath(String jarName) { >>>> configurations.testCompile.find({ it.name.startsWith(jarName) >>>> }).absolutePath >>>> } >>>> >>>> >>>> /** to specify the source for java and resources for test task, by >>>> default this is refered to src/test folder in gradle and maven*/ >>>> sourceSets { >>>> test { >>>> java { >>>> srcDir "src/main/java" >>>> } >>>> resources { >>>> srcDir "src/main/resources" >>>> } >>>> } >>>> } >>>> >>>> test { >>>> systemProperty "metaFilters", System.getProperty("metaFilters", "") >>>> doFirst { >>>> copy { >>>> from(zipTree(jarPath("jbehave-core"))) { >>>> include "style/*" >>>> } >>>> into("build/reports/jbehave/view") >>>> >>>> } >>>> copy { >>>> from(zipTree(jarPath("jbehave-site-resources"))) { >>>> include "js/**/*" >>>> include "style/**/*" >>>> include "images/*" >>>> } >>>> into("build/reports/jbehave/view") >>>> } >>>> } >>>> systemProperties System.getProperties() >>>> dependsOn([clean,copyStories,copyJbehaveUtilities,copyJbehaveStyle]) >>>> } >>>> >>>> >>>> apptechJBehaveStories.java >>>> >>>> package com.apptech.qmo; >>>> >>>> import com.apptech.qmo.ipt.QMOHtmlOutput; >>>> import com.apptech.qmo.ipt.QMOStoryData; >>>> import com.apptech.qmo.ipt.QMOStoryReporterBuilder; >>>> import com.apptech.qmo.ipt.utils.Loggers; >>>> import com.google.common.util.concurrent.MoreExecutors; >>>> import org.apache.log4j.Logger; >>>> import org.apache.log4j.PropertyConfigurator; >>>> import org.jbehave.core.Embeddable; >>>> import org.jbehave.core.configuration.Configuration; >>>> import org.jbehave.core.embedder.Embedder; >>>> import org.jbehave.core.embedder.StoryControls; >>>> import org.jbehave.core.embedder.StoryTimeouts; >>>> import org.jbehave.core.failures.FailingUponPendingStep; >>>> import org.jbehave.core.failures.PendingStepStrategy; >>>> import org.jbehave.core.i18n.LocalizedKeywords; >>>> import org.jbehave.core.io.CodeLocations; >>>> import org.jbehave.core.io.LoadFromClasspath; >>>> import org.jbehave.core.io.StoryFinder; >>>> import org.jbehave.core.junit.JUnitStories; >>>> import org.jbehave.core.model.ExamplesTableFactory; >>>> import org.jbehave.core.model.TableTransformers; >>>> import org.jbehave.core.parsers.RegexStoryParser; >>>> import org.jbehave.core.reporters.CrossReference; >>>> import org.jbehave.core.reporters.Format; >>>> import org.jbehave.core.reporters.HtmlTemplateOutput; >>>> import org.jbehave.core.reporters.StoryReporterBuilder; >>>> import org.jbehave.core.steps.InjectableStepsFactory; >>>> import org.jbehave.core.steps.ParameterControls; >>>> import org.jbehave.core.steps.ParameterConverters; >>>> import org.jbehave.core.steps.spring.SpringStepsFactory; >>>> import org.jbehave.web.selenium.*; >>>> import org.springframework.context.ApplicationContext; >>>> import >>>> org.springframework.context.annotation.AnnotationConfigApplicationContext; >>>> >>>> import java.net.URL; >>>> import java.text.SimpleDateFormat; >>>> import java.util.ArrayList; >>>> import java.util.Arrays; >>>> import java.util.List; >>>> import java.util.Properties; >>>> >>>> import static com.apptech.qmo.ipt.utils.DriverProvider.driver; >>>> import static org.jbehave.core.io.CodeLocations.codeLocationFromClass; >>>> import static org.jbehave.core.io.CodeLocations.getPathFromURL; >>>> import static org.jbehave.core.reporters.Format.*; >>>> >>>> public class apptechJbehaveStories extends JUnitStories { >>>> private static final String _STORIES_SEPARATOR = ","; >>>> public static QMOHtmlOutput qmoHtmlOutput; >>>> public static QMOStoryData storyData; >>>> public static List<String> storyToExecute = null; >>>> static CrossReference crossReference = new >>>> CrossReference().withJsonOnly().withOutputAfterEachStory(true); >>>> Logger log = Logger.getLogger(apptechJbehaveStories.class); >>>> PendingStepStrategy pendingStepStrategy = new >>>> FailingUponPendingStep(); >>>> ContextView contextView = new LocalFrameContextView().sized(640, >>>> 120); >>>> SeleniumContext seleniumContext = new SeleniumContext(); >>>> // SeleniumStepMonitor stepMonitor = new >>>> SeleniumStepMonitor(contextView, >>>> seleniumContext,crossReference.getStepMonitor()); >>>> Format[] formats = new Format[]{new >>>> SeleniumContextOutput(seleniumContext), Format.CONSOLE, XML, Format.HTML}; >>>> StoryReporterBuilder reporterBuilder = new >>>> QMOStoryReporterBuilder(storyData) >>>> >>>> .withCodeLocation(codeLocationFromClass(apptechJbehaveStories.class)).withFailureTrace(true) >>>> >>>> .withFailureTraceCompression(true).withDefaultFormats().withFormats(formats) >>>> .withCrossReference(crossReference); >>>> private ApplicationContext applicationContext; >>>> private WebDriverProvider driverProvider = new >>>> PropertyWebDriverProvider(); >>>> private WebDriverSteps lifecycleSteps = new >>>> PerStoriesWebDriverSteps(driverProvider); >>>> >>>> public apptechJbehaveStories() { >>>> super(); >>>> try { >>>> System.setProperty("webdriver.chrome.driver", >>>> "src/main/resources/drivers/chromedriver.exe"); >>>> storyData = new QMOStoryData(); >>>> String path = >>>> apptechJbehaveStories.class.getProtectionDomain().getCodeSource().getLocation().getPath() >>>> + "stories/log4j.properties"; >>>> PropertyConfigurator.configure(path); >>>> if (lifecycleSteps instanceof PerStoriesWebDriverSteps) { >>>> >>>> configuredEmbedder().useExecutorService(MoreExecutors.newDirectExecutorService()); >>>> } >>>> } catch (Exception e) { >>>> e.printStackTrace(); >>>> } >>>> } >>>> >>>> @Override >>>> public Configuration configuration() { >>>> new WebDriverScreenshotOnFailure(driverProvider, new >>>> QMOStoryReporterBuilder()); >>>> Class<? extends Embeddable> embeddableClass = this.getClass(); >>>> Properties viewResources = new Properties(); >>>> viewResources.put("decorateNonHtml", "true"); >>>> LoadFromClasspath resourceLoader = new >>>> LoadFromClasspath(embeddableClass); >>>> TableTransformers tableTranformers = new TableTransformers(); >>>> // Start from default ParameterConverters instance >>>> ParameterConverters parameterConverters = new >>>> ParameterConverters(resourceLoader, tableTranformers); >>>> ExamplesTableFactory examplesTableFactory = new >>>> ExamplesTableFactory(new LocalizedKeywords(), resourceLoader, >>>> parameterConverters, tableTranformers); >>>> // add custom converters >>>> parameterConverters.addConverters(new >>>> ParameterConverters.DateConverter(new SimpleDateFormat("yyyy-MM-dd")), >>>> new >>>> ParameterConverters.ExamplesTableConverter(examplesTableFactory)); >>>> >>>> return new >>>> SeleniumConfiguration().useSeleniumContext(seleniumContext) >>>> .useWebDriverProvider(driverProvider) >>>> .usePendingStepStrategy(pendingStepStrategy) >>>> .useStoryControls(new >>>> StoryControls().doResetStateBeforeScenario(true)) >>>> .useStoryLoader(new >>>> LoadFromClasspath(apptechJbehaveStories.class)) >>>> .useStoryParser(new >>>> RegexStoryParser(examplesTableFactory)) >>>> .useStoryReporterBuilder(new >>>> QMOStoryReporterBuilder(storyData) >>>> >>>> .withCodeLocation(CodeLocations.codeLocationFromPath(getClassPath())) >>>> .withFailureTrace(true) >>>> .withFailureTraceCompression(true) >>>> .withCrossReference(crossReference) >>>> .withDefaultFormats() >>>> .withFormats(Format.CONSOLE, Format.HTML, >>>> Format.XML,Format.STATS)) >>>> .useParameterControls(new ParameterControls() >>>> .useDelimiterNamedParameters(true)) >>>> .useParameterConverters(parameterConverters) >>>> .useStepMonitor(crossReference.getStepMonitor()); >>>> } >>>> >>>> private List<String> getMetaFilters() { >>>> String metaFilterStr = System.getProperty("meta.filter"); >>>> metaFilterStr = metaFilterStr == null ? "" : metaFilterStr; >>>> List<String> metaFilters = >>>> Arrays.asList(metaFilterStr.split(",")); >>>> log.info("**** MetaFilters = " + metaFilters); >>>> return metaFilters; >>>> } >>>> >>>> private String getClassPath() { >>>> URL fileUrl = codeLocationFromClass(this.getClass()); >>>> String classpath = getPathFromURL(fileUrl); >>>> System.out.println("getClassPath classpath = " + classpath); >>>> // class may come from a jar file >>>> if (classpath.endsWith(".jar!")) { >>>> int idx = classpath.lastIndexOf('.'); >>>> classpath = classpath.substring(0, idx); >>>> } >>>> return classpath; >>>> } >>>> >>>> @Override >>>> public InjectableStepsFactory stepsFactory() { >>>> if (this.applicationContext == null) { >>>> AnnotationConfigApplicationContext applicationContext = new >>>> AnnotationConfigApplicationContext(com.apptech.qmo.ipt.configurations.SpringConfiguration.class); >>>> this.applicationContext = applicationContext; >>>> } >>>> return new SpringStepsFactory(configuration(), >>>> this.applicationContext); >>>> } >>>> >>>> public static class CustomTimeoutParser implements >>>> StoryTimeouts.TimeoutParser { >>>> >>>> public boolean isValid(String timeout) { >>>> return timeout.matches("(\\d+)secs"); >>>> } >>>> >>>> public long asSeconds(String timeout) { >>>> return >>>> Long.parseLong(org.apache.commons.lang3.StringUtils.substringBefore(timeout, >>>> "secs")); >>>> } >>>> >>>> } >>>> >>>> @Override >>>> public void run() throws Throwable { >>>> Embedder embedder = configuredEmbedder(); >>>> embedder.useMetaFilters(getMetaFilters()); >>>> // These should be enabled so that even though the stories fail >>>> it wont go to catch method. Its useful when running multiple scenarios >>>> embedder.embedderControls().doIgnoreFailureInStories(true); >>>> embedder.embedderControls().doIgnoreFailureInView(false); >>>> embedder.embedderControls().doGenerateViewAfterStories(true); >>>> >>>> embedder.configuration().storyControls().doIgnoreMetaFiltersIfGivenStory(true); >>>> embedder.useTimeoutParsers(new CustomTimeoutParser()); >>>> List<String> storyPaths = storyPaths(); >>>> try { >>>> embedder.runStoriesAsPaths(storyPaths); >>>> } catch (Exception e) { >>>> Loggers.CONSOLE_LOGGER.error("STORY FAILED DUE TO:"); >>>> e.printStackTrace(System.err); >>>> Loggers.FILE_LOGGER.error("STORY FAILED DUE TO:"); >>>> e.printStackTrace(System.err); >>>> Loggers.CONSOLE_LOGGER.info("Driver instance is closing"); >>>> Loggers.FILE_LOGGER.info("Driver instance is closing"); >>>> embedder.generateCrossReference(); >>>> throw new Throwable(e.fillInStackTrace()); >>>> } finally { >>>> try { >>>> Loggers.CONSOLE_LOGGER.info("Driver instance is >>>> closing"); >>>> driver.quit(); >>>> Loggers.FILE_LOGGER.info("Driver instance is closing"); >>>> } catch (Exception e) { >>>> System.out.println("Issue in closing driver instance in >>>> run method: " + e.getMessage());// Wantedly not caught the exception >>>> } >>>> embedder.generateCrossReference(); >>>> } >>>> } >>>> >>>> public String getStoryFromStoryPaths(String storyName, List<String> >>>> storyPaths) { >>>> for (String story : storyPaths) { >>>> System.out.println("story = " + story); >>>> int stroryLength = story.split("/").length; >>>> if (story.split("/")[stroryLength - >>>> 1].equalsIgnoreCase(storyName)) return story; >>>> } >>>> return ""; >>>> } >>>> >>>> @Override >>>> protected List<String> storyPaths() { >>>> final List<String> globList = new ArrayList<String>(); >>>> final String[] globs = storyFilter().split(_STORIES_SEPARATOR); >>>> for (final String story : globs) { >>>> globList.add("**/*" + story + (story.endsWith(".story") ? >>>> "" : ".story")); >>>> } >>>> String classpath = getClassPath(); >>>> log.info("classpath=" + classpath); >>>> List<String> paths = new StoryFinder().findPaths(classpath, >>>> globList, null); >>>> log.info("**** story paths = " + paths.toString()); >>>> return paths; >>>> } >>>> >>>> private String storyFilter() { >>>> String storyFilter = System.getProperty("story.filter"); >>>> if (storyFilter == null) { >>>> storyFilter = ""; >>>> } >>>> return storyFilter; >>>> } >>>> >>>> public String captureReportName() { >>>> String storyName = null; >>>> String fileNames[] = reporterBuilder.outputDirectory().list(); >>>> for (int i = 0; i < fileNames.length; i++) { >>>> if (fileNames[i].contains("html") & >>>> !fileNames[i].contains("BeforeStories")) { >>>> String name[] = fileNames[i].split(".html"); >>>> storyName = name[0]; >>>> } >>>> } >>>> return storyName; >>>> } >>>> } >>>> >>>> >>>> >>>> On Thursday, February 22, 2018 at 12:19:29 PM UTC-6, mauro.talevi wrote: >>>>> >>>>> You need to provide a sample project that reproduces the issue for us >>>>> to help you. >>>>> >>>>> On 21 Feb 2018, at 16:39, Maganti Suryanarayana murthy < >>>>> [email protected]> wrote: >>>>> >>>>> Any help on this >>>>> ? >>>>> >>>>> On Tuesday, February 20, 2018 at 10:16:58 AM UTC-6, Maganti >>>>> Suryanarayana murthy wrote: >>>>>> >>>>>> Any one is facing above issue ? >>>>>> >>>>>> On Tuesday, February 20, 2018 at 9:42:28 AM UTC-6, Maganti >>>>>> Suryanarayana murthy wrote: >>>>>>> >>>>>>> Jbehave story report is not showing the time in report i.e., the >>>>>>> Duration is shown as 00:00:00.000. I am using gradle as a build tool. >>>>>>> >>>>>> >>>>> -- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "JBehave User" group. >>>>> To unsubscribe from this group and stop receiving emails from it, send >>>>> an email to [email protected]. >>>>> To post to this group, send email to [email protected]. >>>>> To view this discussion on the web, visit >>>>> https://groups.google.com/d/msgid/jbehave-user/6376be18-29ad-444f-9670-79a4a6eae694%40googlegroups.com >>>>> <https://groups.google.com/d/msgid/jbehave-user/6376be18-29ad-444f-9670-79a4a6eae694%40googlegroups.com?utm_medium=email&utm_source=footer> >>>>> . >>>>> For more options, visit https://groups.google.com/d/optout. >>>>> >>>>> >>>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "JBehave User" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to [email protected]. >>>> To post to this group, send email to [email protected]. >>>> To view this discussion on the web, visit >>>> https://groups.google.com/d/msgid/jbehave-user/045c006d-6548-466d-ab71-311b365880e6%40googlegroups.com >>>> <https://groups.google.com/d/msgid/jbehave-user/045c006d-6548-466d-ab71-311b365880e6%40googlegroups.com?utm_medium=email&utm_source=footer> >>>> . >>>> For more options, visit https://groups.google.com/d/optout. >>>> >>>> -- >>> You received this message because you are subscribed to a topic in the >>> Google Groups "JBehave User" group. >>> To unsubscribe from this topic, visit >>> https://groups.google.com/d/topic/jbehave-user/aKfyLJmdsyY/unsubscribe. >>> To unsubscribe from this group and all its topics, send an email to >>> [email protected]. >>> To post to this group, send email to [email protected]. >>> To view this discussion on the web, visit >>> https://groups.google.com/d/msgid/jbehave-user/604eab3b-5b98-4908-a71b-c6b1680f0354%40googlegroups.com >>> <https://groups.google.com/d/msgid/jbehave-user/604eab3b-5b98-4908-a71b-c6b1680f0354%40googlegroups.com?utm_medium=email&utm_source=footer> >>> . >>> For more options, visit https://groups.google.com/d/optout. >>> >> > > -- > *Regards,* > Gajendra Sahu > -- You received this message because you are subscribed to the Google Groups "JBehave User" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send an email to [email protected]. To view this discussion on the web, visit https://groups.google.com/d/msgid/jbehave-user/CALPCmQ1f0R6BZ_UWPdCFw4fBgR40gqfjmWoYvfj1eY8hhR_T1g%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
