Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Photographer doesn't capture screenshots if an alert dialog is open #532

Closed
mtahat opened this issue Apr 14, 2020 · 3 comments
Closed

Photographer doesn't capture screenshots if an alert dialog is open #532

mtahat opened this issue Apr 14, 2020 · 3 comments

Comments

@mtahat
Copy link

mtahat commented Apr 14, 2020

Hello @jan-molak I am using Serenity-js with Cucumber, protractor & typescript ( see dependencies below) .

One of my test cases start showing Chrome Alert,
image

I was able to by pass the alert by this interaction ( thank's to one of your posts)
image

**Even though I was able to navigate away, the screenshot broke the test!** 
[Photographer:TakePhotosOfInteractions] Taking screenshot of 'AcceptAlert'... - UnexpectedAlertOpenError: unexpected alert open: {Alert text : }

###Is there any workaround I can implement to skip taking screenshot for this Interaction?
I tried a lot of things but nothing seems to work.. I tried to remove the photographer from protractor.config and pass it as actor in the before hook Photographer.whoWill(TakePhotosOfInteractions), then in the After hook I ran it with another photographer who only takes screenshot for failures, but that didn't work as well.

@jan-molak any help will be appreciated!
Thanks

FYI: I used the template cucumber/serenity template that you have here to build my project. see dependencies below, I am also using Mac book, VS Code IDE.

Hooks.ts

import { actorCalled, actorInTheSpotlight, Log } from '@serenity-js/core';
import { ExecuteScript, ResizeBrowserWindow } from '@serenity-js/protractor';
import { After, Before } from 'cucumber';

Before( () => actorCalled('User').attemptsTo(
    ResizeBrowserWindow.toMaximum(),
));

After(() => actorInTheSpotlight().attemptsTo(
    ExecuteScript.sync(`window.sessionStorage.clear()`),
    ExecuteScript.sync(`window.localStorage.clear()`),
    Log.the('Session Cleared!'),
));

Dependencies

"dependencies": {
    "@types/cucumber": "^6.0.1",
    "@types/node": "^12.12.27",
    "axios": "^0.19.2",
    "chromedriver": "^79.0.3",
    "cucumber": "^6.0.5",
    "cucumber-html-reporter": "^5.1.0",
    "cucumber-junit": "^1.7.1",
    "dotenv": "^8.2.0",
    "is-ci": "^2.0.0",
    "moment": "^2.24.0",
    "npm-failsafe": "^0.4.1",
    "protractor": "^5.4.3",
    "rimraf": "^3.0.2",
    "ts-node": "^8.6.2",
    "tslint": "^5.20.1",
    "tslint-microsoft-contrib": "^6.2.0",
    "typescript": "^3.7.5"
  },
  "devDependencies": {
    "@serenity-js/assertions": "^2.1.5",
    "@serenity-js/console-reporter": "^2.1.5",
    "@serenity-js/core": "^2.1.5",
    "@serenity-js/cucumber": "^2.1.5",
    "@serenity-js/protractor": "^2.1.5",
    "@serenity-js/rest": "^2.1.5",
    "@serenity-js/serenity-bdd": "^2.1.5",
    "lodash": "^4.17.15"
  }

Protractor.config

require('dotenv').config()
const
    { ConsoleReporter } = require('@serenity-js/console-reporter'),
    { ArtifactArchiver } = require('@serenity-js/core'),
    { Photographer, TakePhotosOfInteractions } = require('@serenity-js/protractor'),
    { SerenityBDDReporter } = require('@serenity-js/serenity-bdd'),
    isCI = require('is-ci');

var tags = ['@' + process.env.OPCO];
if(process.env.TAGS) {
    const tagArray = process.env.TAGS.split(',');
    tags = tags.concat(tagArray);
    console.log('tags applied: ', tags);
}    
exports.config = {
    baseUrl: `https://abc.${process.env.SITE}.com`,
    SELENIUM_PROMISE_MANAGER: false,
    seleniumAddress: `http://${process.env.HUB}:4444/wd/hub`,
    

    allScriptsTimeout: 110000,

    framework:      'custom',
    frameworkPath:  require.resolve('@serenity-js/protractor/adapter'),

    specs: [ 'features/**/*.feature' ],

    serenity: {
        runner: 'cucumber',
        crew: [
            ArtifactArchiver.storingArtifactsAt('./target/site/serenity'),
            ConsoleReporter.forDarkTerminals(),
            Photographer.whoWill(TakePhotosOfInteractions),
            new SerenityBDDReporter(),
        ]
    },

    cucumberOpts: {
        require: [ 'features/**/*.ts'],
        'require-module':   [ 'ts-node/register'],
        tags:    tags,
        strict:  false,
    },

    capabilities: {
        browserName: 'chrome',

        // see https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities#loggingpreferences-json-object
        loggingPrefs: {
            browser: 'SEVERE' // "OFF", "SEVERE", "WARNING", "INFO", "CONFIG", "FINE", "FINER", "FINEST", "ALL".
        },

        'goog:chromeOptions': {
            args: [
                '--incognito',
                //'--headless',
                '--no-sandbox',
                '--disable-infobars',
                '--disable-extensions',
                '--log-level=3',
                '--disable-gpu',
                '--window-size=1920,1080',
            ].concat(isCI ? ['--headless'] : []),
            'w3c': false    // run in headless mode on the CI server
        }
    }
};
@jan-molak
Copy link
Member

jan-molak commented Apr 15, 2020

Hey @mtahat - good catch, I haven't considered how the photographer would interact with JavaScript alerts yet. Based on your experience, it looks like it doesn't like them. Sorry about that.

The easiest way to work around this would be to take screenshots only upon failures, so:

Photographer.whoWill(TakePhotosOfFailures),

Another workaround would be to, as a temporary measure until Serenity/JS provides a native way to do it, implement the AcceptAlert as a Task rather than an Interaction. Since the Photographer only looks at Interactions, that should make it ignore it.

So something along the lines of:

import { PerformsActivities, UsesAbilities, Task } from '@serenity-js/core';

export class AcceptAlert extends Task {
    performsAs(actor: PerformsActivities & UsesAbilities): Promise<void> {
        return new Promise((resolve, reject) => {
            protractor.browser.switchTo().alert().accept().then(resolve, reject);
        });
    }

    toString() {
        return `#actor dismisses an alert`;
    }
}

@jan-molak jan-molak changed the title [Photographer:TakePhotosOfInteractions] Taking screenshot of 'Interaction... - UnexpectedAlertOpenError: unexpected alert open: {Alert text : } Photographer doesn't capture a screenshot when an alert dialog is open Apr 15, 2020
@jan-molak jan-molak added this to Ideas in Serenity/JS Board via automation Apr 15, 2020
@jan-molak jan-molak moved this from Ideas to To do in Serenity/JS Board Apr 15, 2020
@jan-molak jan-molak changed the title Photographer doesn't capture a screenshot when an alert dialog is open Photographer doesn't capture screenshots if an alert dialog is open Apr 15, 2020
@MJavedAli
Copy link

I tried the first option - It took to screenshot , but was not appended in the html report -

image

For the second workaround - i am not clear where to put these code ? or how where to call them . currently my after hooks looks like this -

image

@jan-molak
Copy link
Member

Hi @mtahat!

Serenity/JS 2.13.0 introduced support for handling modal dialog windows, so you can now say:

import { Accept, ModalDialog } from '@serenity-js/protractor';

actorInTheSpotlight().attemptsTo(
    Accept.the(ModalDialog.window()),
)

Also, changes introduced in 2.17.3 make the Photographer ignore the UnexpectedAlertOpenError, so it will ignore the alert and move on.

Hope this helps!
Jan

Serenity/JS Board automation moved this from To do to Done Oct 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

No branches or pull requests

3 participants