Cypress test scenario logging in Via Auth0 - function

I've started using Cypress to test our front End Internal Application (being built using Angular5), which uses Auth0 as login authentication.
I'm a QA with NO experience of any sort of coding, so I was quite pleased when I managed to get a few tests working (and passing).
However I have hit a stumbling block. Even though I can use Cypress to test that the Auth0 login works; when the login is successful it is not opening the application in the test as it would if I were manually testing.
Below is my test that runs the Auth0 authentication test.
describe('My Login Test', function (){
it('Visit Risk App Landing Page', function (){
const typedText = 'user-email-address'
cy.visit('http://localhost:3000/workflow')
cy.get('button').click()
cy.get('input.auth0-lock-input').first()
.type(typedText)
.should('have.value', typedText)
cy.get('button').click()
cy.url().should('eq','http://localhost:3000/workflow')
})
})
I'm also trying to create a function where I can call Auth0 and store the response so I don't have to run a login scenario before every tests that runs for the rest of the application, but as I said I have no coding experience and I've found that creating a function is far different to creating a test as that shown above.
If anyone could offer any suggestions/tips/clues, they would all be appreciated.

can't help you with your first question. But as for extracting your login code for reusablitity you could create a cypress command https://docs.cypress.io/api/cypress-api/custom-commands.html#Syntax
Cypress.Commands.add('login', (email, password) => {
cy.visit('http://localhost:3000/workflow')
cy.get('button').click()
cy.get('input.auth0-lock-input').first()
.type(email)
cy.get('button').click()
cy.url().should('eq','http://localhost:3000/workflow')
})
Then from within your tests you could call it like:
cy.login('some-email', 'somepassword')

Related

ChainableTemporaryCredentials getPromise and Missing credentials in config, if using AWS_CONFIG_FILE

I have an node application deployed in GCP.
The application includes code to access ressources in AWS-cloud.
For this purpose it uses the aws-SDK with ChainableTemporaryCredentials.
The relevant code lines are...
const credentials = new ChainableTemporaryCredentials({
params: {
RoleArn: `arn:aws:iam::${this.accountId}:role/${this.targetRoleName}`,
RoleSessionName: this.targetRoleName,
},
masterCredentials: new WebIdentityCredentials({
RoleArn: `arn:aws:iam::${this.proxyAccountId}:role/${this.proxyRoleName}`,
RoleSessionName: this.proxyRoleName,
WebIdentityToken: token,
}),
})
await credentials.getPromise()
The WebIdentityToken was received from google and looks good.
At AWS-side I created an proxy-role (the line from masterCredentials RoleArn).
However at runtime I get the error:
Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1
I do not understand this error. Because my application runs in GCP and I use temporary credentials I do not understand why I should use aws-credentials in form of an credentials file or environment variables like AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY. I thought the idea to use ChainableTemporaryCredentials is NOT to have direct aws-credentials. Right?
You can see the public code at:
https://github.com/cloud-carbon-footprint/cloud-carbon-footprint/blob/trunk/packages/aws/src/application/GCPCredentials.ts
and documentation regarding env-variables at:
https://www.cloudcarbonfootprint.org/docs/configurations-glossary/
Any help which leads to understanding of this error message is welcome.
Thomas
Solved it. "Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1 was totally misleading." In reality it was a problem with the field-names in the GCP-JWT-token und the policy in aws. See https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#ck_aud

Laravel dusk test fails on CI (github actions) but succeeds locally

One of our tests fails on CI, while running the test locally results in the test passing. I've been trying to figure out why for hours/days now, and I still can't seem to fix it.
The test
The steps of the test are as follows:
Register as a new user
Confirm the sent email in order to login by clicking a link
Once logged in, click a link in the dashboard and check if you're on the page.
// $signup & $address are dusk pages
$browser->visit($signup)
->acceptCookies()
->signup([
'firstName' => 'John',
'email' => 'john.doe#example.org',
'password' => 'john.doe',
])
->on($thanks)
->visitMail($confirmationMail)
->withinMail(fn (DuskBrowser $browser) => $browser->click('#confirmLink'))
->switchToLatestWindow()
->on($dashboard)
->click('#editAddressButton')
->on($address)
Every step succeeds until the last line. When the browser asserts it's on the "address" page, the assertion fails. The assertion is based on seeing certain text displayed.
This makes sense, because when dumping the page (on CI) after clicking #editAddressButton, the page is empty like so: <html><body></body></html>.
All dependencies are up-to-date and the same version, as well for chrome-driver.
Conclusion
I'm just baffled why it fails at that specific point on CI, but not locally. Our other tests do succeed, so it's not like our .env files are setup incorrectly.
Thank you for your time reading this, I sincerely hope that someone can help us figure this out.

Cypress: How to visit a url of a different origin?

I'm new to cypress and have ran into an issue. I have my base URL set to the domain I want to test, the issue is when I want to test the ability to login on my base url site I need to verify the user on another site, once I click apply on site number 2 the page on my base url reloads and I would then be able to test the rest of the site.
When I try to visit site 2 from my test I get an error
cy.visit() failed because you are attempting to visit a URL that is of
a different origin.
The new URL is considered a different origin because the following
parts of the URL are different:
superdomain
You may only cy.visit() same-origin URLs within a single test.
I read this https://docs.cypress.io/guides/guides/web-security.html#Set-chromeWebSecurity-to-false I've tried setting "chromeWebSecurity": false in cypress.json but I still get the same issue (I'm running in chrome)
Is there something I am missing?
As a temporary but solid work around, I was able to find this script in one of the Cypress Git issue threads (I don't remember where I found it so I can't link back to it)
Add the below to your cypress commands file
Cypress.Commands.add('forceVisit', url => {
cy.window().then(win => {
return win.open(url, '_self');
});
});
and in your tests you can call
cy.forceVisit("www.google.com")
From version 9.6.0 of cypress, you can use cy.origin.
If you want to use it, you must first set the "experimentalSessionAndOrigin" record to true.
{
"experimentalSessionAndOrigin": true
}
And here's how to use it.
cy.origin('www.example.com', () => {
cy.visit('/')
})
cy.origin change the baseurl, so you can link to another external link via cy.visit('/').
You can stub the redirect from login site to base site, and assert the URL that was called.
Based on Cypress tips and tricks here is a custom command to do the stubbing.
The login page may be using one of several methods to redirect, so besides the replace(<new-url>) stub given in the tip I've added href = <new-url> and assign(<new-url>).
Stubbing command
Cypress.Commands.add('stubRedirect', () => {
cy.once('window:before:load', (win) => {
win.__location = { // set up the stub
replace: cy.stub().as('replace'),
assign: cy.stub().as('assign'),
href: null,
}
cy.stub(win.__location, 'href').set(cy.stub().as('href'))
})
cy.intercept('GET', '*.html', (req) => { // catch the page as it loads
req.continue(res => {
res.body = res.body
.replaceAll('window.location.replace', 'window.__location.replace')
.replaceAll('window.location.assign', 'window.__location.assign')
.replaceAll('window.location.href', 'window.__location.href')
})
}).as('index')
})
Test
it('checks that login page redirects to baseUrl', () => {
cy.stubRedirect()
cy.visit(<url-for-verifying-user>)
cy.wait('#index') // waiting for the window load
cy.('button').contains('Apply').click() // trigger the redirect
const alias = '#replace' // or '#assign' or '#href'
// depending on the method used to redirect
// if you don't know which, try each one
cy.get(alias)
.should('have.been.calledOnceWith', <base-url-expected-in-redirect>)
})
You can't!
But, maybe it will be possible soon. See Cypress ticket #944.
Meanwhile you can refer to my lighthearted comment in the same thread where I describe how I cope with the issue while Cypress devs are working on multi-domain support:
For everyone following this, I feel your pain! #944 (comment) really gives hope, so while we're patiently waiting, here's a workaround that I'm using to write multi-domain e2e cypress tests today. Yes, it is horrible, but I hope you will forgive me my sins. Here are the four easy steps:
Given that you can only have one cy.visit() per it, write multiple its.
Yes, your tests now depend on each other. Add cypress-fail-fast to make sure you don't even attempt to run other tests if something failed (your whole describe is a single test now, and it makes sense in this sick alternate reality).
It is very likely that you will need to pass data between your its. Remember, we're already on this crazy “wrong” path, so nothing can stop us naughty people. Just use cy.writeFile() to save your state (whatever you might need), and use cy.readFile() to restore it at the beginning of your next it.
Sue me.
All I care about at this point is that my system has tests. If cypress adds proper support for multiple domains, fantastic! I'll refactor my tests then. Until that happens, I'd have to live with horrible non-retriable tests. Better than not having proper e2e tests, right? Right?
You could set the window.location.href manually which triggers a page load, this works for me:
const url = 'http://localhost:8000';
cy.visit(url);
// second "visit"
cy.window().then(win => win.location.href = url);
You will also need to add "chromeWebSecurity": false to your cypress.json configuration.
Note: setting the window to navigate won't tell cypress to wait for the page load, you need to wait for the page to load yourself, or use timeout on get.

Yii2 codeception command did not finished properly

Now I know this Command Did Not Finished Properly means that some die or exit statement occurs somewhere in the way of the test but is there is way to ignore it and see the result from that test ? I'm trying simple basic login test ( I am total newbie in tests ) and I am not sure if the test passes like an expected. It looks like so:
public function validLoginUser(FunctionalTester $I)
{
$I->amOnPage('/admin/user/login');
$I->fillField('login-form[login]', 'toma');
$I->fillField('login-form[password]', '9110033969');
$I->click('Log in');
$I->see('Статистики', 'h4.text-white');
}
I am pretty sure that the test pass successuly. The form is the dektrium extension Yii2 login form. Nothing changed on it. Or maybe the problem is that I am trying to test someone else's code? If it's not how can I see the result? Thank you in advance and I am sorry for the confusing question.
"Command Did Not Finished Properly" message is printed by shutdown handler, there is no way to resume test execution from that point.
If your codebase uses die a lot, you could use PhpBrowser module to test over HTTP instead of using Yii2 module which executes application code in the same process.

REST API for yii2, the authenticator (HttpBearerAuth) is not working on server

I've just created a project for working with REST API (using yii2 framework).
All issues of REST API is working really cool on localhost. But when bringing the project on server (also the same database is taken by), the authorization is not available. Now I'm using "yii\filters\auth\HttpBearerAuth"
Inside the model "implements IdentityInterface", there's finding-token function "findIdentityByAccessToken" that's so simple, the "validateAuthKey" function is returning always true; see below:
public static function findIdentityByAccessToken($token, $type = null){
return static::findOne(["token" => $token]);
}
public function validateAuthKey($token)
{
return true;
}
See any pictures:
https://www.flickr.com/photos/40158620#N03/20701523349/in/dateposted-public/
Anyone can have some experience on this problem, can you tell me how to solve it? Thanks for your kindness.
Note:
The project, I'm following https://github.com/NguyenDuyPhong/yii2_advanced_api_phong (It works fine on localhost; I also deployed exactly the project on my server, it raised the same problem )
To make sure that the server is configured right: I created 2 actions, 1 is authorized, another is not. I checked unauthorized action, it works very well. =======>
actionView is not authorized => getting API info. is ok
actionIndex is authorized by "yii\filters\auth\HttpBearerAuth" => FAIL
In my case the Problem was that the server removes Authorization Header
I needed to add this to .htaccess
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
HttpBearerAuth used $user->loginByAccessToken to authorize see
validateAuthKey used by "loginByCookie"(and it seems that in this case not used)
Try to use QueryParamAuth for test purposes (it's easier to test)