I have a page that I'm able to get accessibility test report from Pa11y 5 using actions.
When I click on a button on that specific page, I get a popup/overlay, I would like Pa11y to sniff that popup/overlay page and report on accessibility metrics, but currently Pa11y 5 is only able to provide me for the main parent page ignoring any reports on the html in the popup page? Is there a way to achieve this, tell Pa11y to switch to popup and sniff on that popup html and report that.
Popup/overlay contains div[role='dialog'] as it is a modal dialog made out of aria.
I'm using the latest Pa11y, hence I keep mentioning it as Pa11y 5. I have not used Pa11y4, so cannot comment if this works with Pa11y 4.
Any help/advise is sincerely appreciated.
Update:
As requested, below is my complete (relevant) part of the code
const PageOptions1 = {
timeout: 30000,
userAgent: 'A11Y TESTS',
actions: [
'screen capture screenshots/001-DefaultView.png'
]
};
const PageOptions2 = {
timeout: 35000,
userAgent: 'A11Y TESTS',
rootElement: 'div[role="dialog"]',
actions: [
'click element button[data-automation-id="ccbutton"]',
'wait for element div[role="dialog"] to be added',
'screen capture screenshots/002-Popup.png',
'click element i.fa-close',
'screen capture screenshots/002-DefaultView.png'
]
};
async function runPa11y(navigateUrl) {
try {
const results = await Promise.all([
pa11y(navigateUrl, PageOptions1),
pa11y(navigateUrl, PageOptions2),
]);
LogResults(results);
} catch (error) {
console.error("Error: " + error.message);
}
}
runPa11y("Url to navigate");
Thanks for your updates! You're doing the right things and everything looks like it's working as expected.
Pa11y will perform all of the Actions before running your test, so it's opening the modal dialog, immediately closing it again, and then running the test without it.
Break PageOptions2 into smaller units so that your last Action is the state you want to test against, and everything should be ok.
Related
I am new to using Cypress for web automation. I am still scouring through the internet looking for answers to this but I cannot find a solution that works for me.
This is what I'm trying to do in my test:
User clicks a link.
A new tab is opened and a windows prompt appears, requesting user input (username, password). (Since Cypress doesn't allow opening new tabs, I've removed the target attribute.)
Upon logging in successfully, the page has a download button.
User clicks on the download button.
The first struggle - I could not enter values into the windows prompt. In the below code, I was trying to see if the 'Sign In' button on the windows prompt would be clicked, but it was not.
cy.window().then(win => {
cy.get('#documentPassword').then((finalPassword) => {
const stub =cy.stub(win, 'prompt')
stub.returns('test')
cy.get('button#signin').click()
})
})
I got an Assertion Error: Timed out retrying after 25000ms: Expected to find element: button#signin, but never found it.
After no luck with this, I moved on to another suggestion.
The second struggle - I tried putting the username and password into the link, like this: https://username:password#mytestingwebsite.com. Just to note, when I paste the link manually into a browser, it works. To test this out, this what I had done:
cy.visit('https://mailtrap.io')
// ...other steps
cy.forceVisit('https://username:password#mytestingwebsite.com')
I added a custom command forceVisit to the commands.js file:
Cypress.Commands.add('forceVisit', url => {
cy.window().then(win => {
return win.open(url, '_self');
});
});
The result is the second url does not load.
Hoping for any insight from you guys. Thanks in advance.
This works for me:
cy.visit('https://mytestingwebsite.com', {
auth: {
username: 'username',
password: 'password'
}
})
This didn't work for me the first time I tried it because I still passed the credentials in the url.
I need to run my custom protocol twice but it doesn't work the second time, I got this error ( Not allowed to launch 'cutomProtocol' because user gesture is required. ) I tried to find a solution but I did not find any!
Same problem with chrome, firefox and edge.
I need to see this popup twice
window.location.href = 'my-protocol://${base64}';
and
customProtocolVerify(
`my-protocol://${base64}`,
() => {
// successCb: Callback function which gets called when custom protocol is found.
console.log('My protocol found and opened the file successfully..');
},
() => {
// failCb: Callback function which gets called when custom protocol not found.
console.log('My protocol not found.');
}
);
I tried with these two and didn't work
Clarification
I have a custom protocol.
My scenario:
check if it's installed successfully (I'm using customProtocolVerify method) and that method makes the launch if the protocol is found
run some APIs
launch the protocol again
My problem:
Step 3 doesn't work, I have the error on the console that says " Not allowed to launch... " and of course I can't see my popup to open my protocol.
I'm asking for help to make step 3 work
The only way to bypass this "bug" is to ask the user twice (or in a loop) by showing a OK alert or some sort of user confirm box.
My solution:
OpenLinkInExternalApp(Link);
alerty.alert('', { title: '', okLabel: 'Open Link' }, function () {
OpenLinkInExternalApp(Link);
});
The above code will open the external app, then a OK alert will pop up, after clicking OK, I call the same code again. Do this in a loop if needed.
TIP:
We guide our users to use split screen at this stage. This is where users can dock your web-app on the left and the external app on the right as an example.
Alert Box:
We user Alerty.js https://github.com/undead25/alerty#readme
I am using node-webshot utility to capture screenshot of an angularJS based website.
I have the following code which is partially working.
const webshot = require('webshot');
var options = {
streamType: 'png',
windowSize: {
width: 2048,
height: 2048
},
shotSize: {
width: 'all',
height: 'all'
}
};
webshot('URL here', 'image.png', options, function(err) {
if(err){
console.log("An error ocurred ", err);
}
else{
console.log("Job done mate :)")
}
});
It works fine for simple websites like google.com e.t.c, but the only problem is that the angular js website i am trying to fetch information from loads the default page first, then loads some additional bits (Forms, UI stuff) e.t.c after few seconds since it makes some http calls in the background.
I have tried using renderDelay property and set it to a large value. it does wait for that time, but still image is just a blank image.
As per their doucmentation set this
takeShotOnCallback false Wait for the web page to signal to webshot
when to take the photo using window.callPhantom('takeShot');
Now i can put this takeShotOnCallback in my properties above, but in the angular app, when i try to write this window.callPhantom, it gives me the error that method doesn't exist.
So how should i use this?
Another broader question is, does Node webshot is the right tool to capture screenshot for Angular 6 website. Or should i look for some other solution.
In one of our tests, sometimes we get the browser alert message when the user is trying to log out.
I do not want the tests failed due to these alerts. We are getting the below error when there is an alert:
An error was thrown in an afterAll
AfterAll Failed: unexpected alert open: {Alert text : You have unsaved changes! If you leave, your changes will be lost.}
I have tried to resolve it by
1. added unexpectedAlertBehaviour: 'accept' to the conf.js file, which failed, and 2, modifying the code using an if/else block as follows:
exports.logOutfromESY =function(){
var G = GV;
var EC = protractor.ExpectedConditions;
expect(G.User_Menu_Dropdown.isPresent()).toBeTruthy();
G.User_Menu_Dropdown.click();
browser.wait(EC.presenceOf(G.logOut_Button), 2000, 'The Logout Buttons taking too long to appear in the DOM');
G.logOut_Button.click();
browser.sleep(500);
if(alert.isPresent()){
browser.switchTo().alert().then(function (alert) {
alert.accept();
});
}
browser.wait(EC.presenceOf(G.Email_Input_box), 3000, 'The Login Page redirection taking long time');
browser.sleep(500);
};
It did not work either. Note that the "alert" variable was my last ditch effort to make protractor to identify the alert.
Is there any way to achieve this?
Seems that this solution may be helpful:
https://stackoverflow.com/a/29873887/6331748
EDIT:
You can also consider to use --disable-notifications flag.
You need to add it in your config file like that:
export const config = {
capabilities: {
chromeOptions: {
args: ['--disable-notifications']
}
}
}
I am using protractor for the first time and doesn't know how to add custom screenshots to jasmine report.
Currently i am have done some thing like this.
onPrepare:
jasmine.getEnv().addReporter(
new Jasmine2HtmlReporter({
takeScreenshots: true,
takeScreenshotsOnlyOnFailures: false,
consolidate: true,
consolidateAll: true,
filePrefix: 'Report',
screenshotsPath: './screenshots/',
reportPath: './pageObject/reports/'
})
);
And added the code to take the screenshot.
browser.takeScreenshot().then(function (png) {
test.writeScreenShot(png,screenshotName+ '.png');
});
test.writeScreenShot = function(data,filepath){
var stream = fs.createWriteStream(path);
stream.write(new Buffer(data, 'base64'));
stream.end();
};
But now the actual pain comes in, it takes the snapshot of entire page and attach in report which i doesn't want and i want the custom snapshot which i have taken only for specific element and attach it in jasmine report.
I couldn't understand how the snapshot is added to the report . can some help me how the snapshot is added automatically to the report so that i can try once for the custom snapshot taken by me and try adding it to the report.
Thanks in advance.
Making screenshots of a certain area is not supported by selenium itself as far as I known. You can only make a screenshot of the visible page.
If you are struggling with screenshots, have a look at https://github.com/azachar/protractor-screenshoter-plugin
(disclaimer: I am the author of the fork)
You can make screenshots on each expectation. Also, it comes with an HTML-based report so it is easy to understand why your tests are failing.