Code Monkey home page Code Monkey logo

Comments (23)

prescottprue avatar prescottprue commented on June 12, 2024 2

Oh, I really like that idea! Much reads much more clearly. We may want to make that an object though, so we can select by key (I think that is what you actually meant to put):

{
  "TEST_UIDS": {
    "role1": "<some_uid>",
    "role2": "<some_uid>"
  }
}

Cool, I'll add this as a feature to build. Feel free to make a PR if you get a chance, if not I will try to get to it when I can.

from cypress-firebase.

prescottprue avatar prescottprue commented on June 12, 2024 2

When starting to investigate I realized that this could create some difficult if multiple logins happen without logout happening first. It is tough to estimate a time, I'll continue to investigate and post updates here.

from cypress-firebase.

TapaiBalazs avatar TapaiBalazs commented on June 12, 2024 1

I just add my two cents here:
I have a really small app with only user and admin roles, and I serve one app instance on localhost:1111 for the simple user and on localhost:2222 for the admin user tests. They can run parallelly, requires some small effort for visiting the proper URL in the actual tests.
I know it might not be that cost effective or ideal to run an instance for every role just to be able to test them parallelly, but that could be a workaround.

from cypress-firebase.

fabiocarneiro avatar fabiocarneiro commented on June 12, 2024 1

I would like to have it like this:

cy.firebaseSignUp(email, password)
cy.firebaseSignIn(email, password)

other authentication options would also be interesting

I think there is some coupling between two independent problems here:

  • Obtaining credentials or managing for an already registered user by using admin access
  • Registering and Authenticating a user that you have credentials for

Basically, my goal is to have the testing suite to create a new user every time I run the test, avoiding the state of previous tests to influence the result, or requiring a clean up of the state after each run.

The current library implementation forces the usage of a single user or a specific authentication method. IMHO, that is not ideal.

from cypress-firebase.

fabiocarneiro avatar fabiocarneiro commented on June 12, 2024 1

It does - it calls createCustomToken internally

@prescottprue The only concern I have with that is that it is assuming I do have specific accounts that I want to test with, and I will hardcode the ids on my code. This adds some fragility, as there can be different states based on these accounts on different runs and the accounts can be modified/removed outside of the scope of the application you are testing.

It would still be nice to have support to create an account during the test. Also, cy.login could be a bit more specific to firebase. Someone new looking at the code will have no clue where this login comes from. For those two reasons I proposed:

cy.firebaseSignUp({email, password})
cy.firebaseSignIn({email, password})

PS1: cy.login could be deprecated but still be working for the next versions
PS2: The SignUp/SignIn approach has the advantage of not requiring admin API.

from cypress-firebase.

prescottprue avatar prescottprue commented on June 12, 2024

It is not currently supported, but this is a feature I for sure want to add. What are you thinking for how to select it? Maybe passing the param name into cy.login like cy.login('TEST_UID2') ?

from cypress-firebase.

aviyam1811 avatar aviyam1811 commented on June 12, 2024

Yeah I think it's good.
Maybe add users section in the config so it looks like:

{
    "TEST_UIDS": [
         "role1": <some_uid>,
         "role2": <some_uid>
]}

And then use it like cy.login("role1")

from cypress-firebase.

aviyam1811 avatar aviyam1811 commented on June 12, 2024

I tried to fix it but currently I don't have time for it.
Could you please estimate an time for this feature to be supported?

from cypress-firebase.

dhair-seva avatar dhair-seva commented on June 12, 2024

I'd be happy to help chip in on making a PR for this. I need this for my team. We have about 4 portals into our app (client with 5 roles, tester portal, captain portal and super portal). I can easily use the current functionality for tester, captain and super. However, the client portal with 5 roles will prove to be difficult.

Couldn't we check the uid that is currently logged in, and if that uid does not match the uid we want to login with, then we logout and then do the login process?

from cypress-firebase.

dhair-seva avatar dhair-seva commented on June 12, 2024

After thinking about it more, I'm thinking that using:

Cypress.env("TEST_UID", TestUsers.superUid)

and then logging out and back in, when needed will give me what I need. Its not ideal and love the idea of TEST_UID being an object. But this might be a good workaround

from cypress-firebase.

Codediggar avatar Codediggar commented on June 12, 2024

Any update on this please.
We use a dedicate function id to run E2E testcases and want to use the same ID in my local machine.
When I run it always takes my ID instead of the Functional ID , even after overriding the login with options.
It gets me a token correctly , auth works but the UI in electron using my ID to login, how to logout and use different ID?

from cypress-firebase.

prescottprue avatar prescottprue commented on June 12, 2024

Work for this is being included in v0.10.0 - it calls a firebase-tools-extra command to generate the custom token dynamically then logs in.

@fabiocarneiro signing in with credentials such as email and password was initially skipped since that would mean either exposing the credentials in the test code or passing them through from the environment. I'm open to the idea of creating custom commands for doing this, but as you said it is really part of a different concern.

In this issue I'm going to address passing a UID to login to a different user (logging in through custom auth token) - we can address creating user's during the test as a different feature. I made #88 to track that.

Something to note is that you aren't locked into a specific auth method per say - you can login any way you want as a user of your app, then grab the UID from the Auth tab of Firebase. Then if you use that UID, it will login with a custom token, but that still works with accounts that were created by other auth methods. This has been preferred for my apps so we aren't building up user accounts over time just from tests running.

from cypress-firebase.

fabiocarneiro avatar fabiocarneiro commented on June 12, 2024

Something to note is that you aren't locked into a specific auth method per say - you can login any way you want as a user of your app, then grab the UID from the Auth tab of Firebase

@prescottprue what I don't like here is the assumption that you will use one user for all your tests and that the authentication happens outside of Cypress, and then the token is used afterwards.

from cypress-firebase.

prescottprue avatar prescottprue commented on June 12, 2024

@fabiocarneiro The logic that is being added in v0.10.0 will allow for logging into different users by passing their UID into cy.login - since the token will be generated on the fly this will allow the usage of multiple users in tests

from cypress-firebase.

fabiocarneiro avatar fabiocarneiro commented on June 12, 2024

@fabiocarneiro The logic that is being added in v0.10.0 will allow for logging into different users by passing their UID into cy.login - since the token will be generated on the fly this will allow the usage of multiple users in tests

Does that use the admin api?

from cypress-firebase.

prescottprue avatar prescottprue commented on June 12, 2024

It does - it calls createCustomToken internally

from cypress-firebase.

prescottprue avatar prescottprue commented on June 12, 2024

Closing since this if a feature within v0.10.0. Anyone that tries it out - reach out if it doesn't work as expected

from cypress-firebase.

Nick-Mazuk avatar Nick-Mazuk commented on June 12, 2024

It does - it calls createCustomToken internally

@prescottprue The only concern I have with that is that it is assuming I do have specific accounts that I want to test with, and I will hardcode the ids on my code. This adds some fragility, as there can be different states based on these accounts on different runs and the accounts can be modified/removed outside of the scope of the application you are testing.

It would still be nice to have support to create an account during the test. Also, cy.login could be a bit more specific to firebase. Someone new looking at the code will have no clue where this login comes from. For those two reasons I proposed:

cy.firebaseSignUp({email, password})
cy.firebaseSignIn({email, password})

PS1: cy.login could be deprecated but still be working for the next versions
PS2: The SignUp/SignIn approach has the advantage of not requiring admin API.

I totally agree and this is really what I was looking for. Ideally, each test should be isolated from one another, and having hard-coded UIDs destroys that isolation. Because one test may update the user profile (e.g. custom claims), and another may depend on the auth claim not changing. Running the tests in the reverse order causes a failing test.

Alternatively, if you don't use that format, it would be okay to have:

cy.createUser({ uid, email, password, customClaims, etc })
cy.removeUser(uid)

from cypress-firebase.

Nick-Mazuk avatar Nick-Mazuk commented on June 12, 2024

@fabiocarneiro

Found a workaround to creating users in the code and cleaning up users afterward. You can essentially add your own cypress commands to create and log-in users by using the front-end firebase code. And if you use firebase's REST API, you can delete all the user accounts after each test.

https://firebase.google.com/docs/reference/rest/auth#section-auth-emulator-clearaccounts

Here are the commands I added to commands.ts (should still work for normal JS). Note that this was only tested using the firebase emulators.

// commands.ts
Cypress.Commands.add('createUser', (email: string, password: string) => {
    Cypress.log({
        displayName: 'createUser',
        consoleProps: () => {
            return { email, password }
        },
    })
    return firebase.auth().createUserWithEmailAndPassword(email, password)
})

Cypress.Commands.add('loginWithEmail', (email: string, password: string) => {
    Cypress.log({
        displayName: 'loginWithEmail',
        consoleProps: () => {
            return { email, password }
        },
    })
    return firebase.auth().signInWithEmailAndPassword(email, password)
})

Cypress.Commands.add('deleteAllUsers', (email: string) => {
    Cypress.log({
        displayName: 'deleteAllUsers',
        consoleProps: () => {
            return { email }
        },
    })
    return cy.request({
        url: 'http://localhost:9099/emulator/v1/projects/{project-id}/accounts',
        method: 'DELETE',
        auth: { bearer: 'owner' },
    })
})

To use these:

// hello-world.test.ts

it('this creates, signs in, and deletes a user', () => {
    cy.createUser('[email protected]', 'useabetterpassword')
    cy.loginWithEmail('[email protected]', 'useabetterpassword')
    cy.deleteAllUsers()
})

from cypress-firebase.

fabiocarneiro avatar fabiocarneiro commented on June 12, 2024

@Nick-Mazuk Looks good and thanks for sharing. I didn't use cypress recently but will for sure come back to it at some point. This should be added to the library. Maybe open a PR?

from cypress-firebase.

felippepuhle avatar felippepuhle commented on June 12, 2024

Is it a good idea exposing the auth interface on the window so I can access directly inside Cypress and call createUserWithEmailAndPassword so user will be already logged in after that? Also, our app uses signInWithPhoneNumber, is there a way I can create a whitelisted user so I can use a static code for the testing step?

from cypress-firebase.

prescottprue avatar prescottprue commented on June 12, 2024

@felippepuhle You shouldn't need to be creating the user through email/password for things to work - just using a new or existing auth user's UID in cy.login will log you in as that user. So no need to call createUserWithEmailAndPassword just call cy.login('someUID') where 'someUID' is the ID you would like to assign

If you are running your tests against a full Firebase project instead of the emulators, you can also create a user through your app the normal way, then use that UID with cy.login even if the account is an email/password provider account or a phone number provider account.

Testing the UI for loggin in with phone number is a different case - for those you will want to have a known user within your auth and actually authenticate with Firebase through the UI instead of using cy.login (but again, this is only for testing the actual login functionality of your app, not other pages, even if they require auth)

If you need more info, feel free to open a discussion 😄

from cypress-firebase.

felippepuhle avatar felippepuhle commented on June 12, 2024

@prescottprue thanks for the explanation and tips!

Yeah, we're running our tests against a full Firebase project... We want to make our tests as isolated as possible (we're running them in parallel in more than 1 browser, and we already fel in some race conditions where 2 browsers were testing the same screen with the same user and the test fails due to that - wrong values on assertions).

Our signup flow is kinda slow (there're a lot of screens, that's the reason we don't want to create a new user through the UI each test), I'm considering using this project to handle the authentication but I'm missing this signup stuff... is there a way we can implement both createUser and deleteUser? I can help with that, just need some help to better understand the project.

Thanks!

from cypress-firebase.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.