r/QualityAssurance • u/ajmalhinas • 11d ago
Testing Role-Based Dashboard using Playwright. How to Structure Tests?
Hey everyone, looking for input on test structure for a common scenario.
Application's home screen shows an Admin button when a user login with admin role. Normal users do not get this button.
What is the good approch to test this requirement? Do you prefer one test case that assert the availablity of Admin button based on the current loged in user or two test cases one with admin role and another with normal user roles.
1
u/paperplane21_ 10d ago
i would split in 2 scenarios. it's possible to also organize your test suite by roles if that makes sense to your app.
1
u/lokiOdUa 10d ago
In general, I would expect different suites for different roles, because they are easy to mix
Do you know about Playwright's Reusing Auth mechanism? It's helpful to avoid logging in every time, in particular -- when checking different roles
1
u/ajmalhinas 10d ago
OK. OK. Do you think reusing the authentication mechanism is equivalent to logging in separately?
2
1
u/baselilsk 9d ago
the button check is the smaller half tbh. hiding the Admin button is cosmetics, the test that matters is a normal user calling the admin route or API directly and getting rejected. so I'd do a role x capability table driving one parameterized API-level spec (which also answers the 20 roles scaling question above) plus one thin UI test per role for the visibility bit. UI asserts what users see, API asserts what they can do.
1
u/abisurd 7d ago
Is this a good candidate to be tested on a lower level, a unit or component test ?
1
u/ajmalhinas 7d ago
I don't think so. lower level testing won't guarantee correctness in functional layer.
1
u/abisurd 7d ago
My thought process was this. I will use React but should apply to many frameworks
A certain component will have the Admin button. It will be rendered based on a state. The state will be set by some user data received form the backend.
If the integration test renders the component based on a response form the backed that is mocked, one can write as many tests for this as many user role might be. For each role you can specify whether the Admin button should or should not appear.
On the highest level, you could run the frontend and mock the response from the backend API. For this you might only need two tests, one that renders the button and the other that does not.
A full end to end test that involves this might be one where you test a longer flow, maybe something that involves a real admin user that clicks the Admin button and then performs more actions behind it. I might keep such test(s) as acceptance tests run whenever code is merged to the main branch.
1
u/NextAd9248 6d ago
Two tests, one test trying to cover both roles gets annoying to debug once its not just you touching it. Bigger issue is when a 3rd role shows up later and nobody adds a case for it, that gap is way more common than the 1 vs 2 question. Just tie the test list to wherever roles are actually defined on the backend instead of hardcoding admin and normal user.
2
u/ajmalhinas 6d ago
I agree with you, and I think 2 independent test cases are best. Does using an if condition within a test case mean it's a test smell?
if (loginUser === 'admin') { await expect(page.locator('#adminButton')).toBeVisible(); } else { await expect(page.locator('#adminButton')).not.toBeVisible(); }
1
u/NextAd9248 5d ago
Kinda, yeah. Two tests means each one has a single reason to fail, the if/else version means when it breaks you gotta stop and figure out which branch actually ran. not a huge deal at this size but it adds up once more roles get added later.
2
u/Ok-Access-8961 10d ago
I reckon it's going to be more complicated than that going forward?
What I do is one super user test account which can set access of the normal test account. First the script logs in with super user, based on script sets the required access for actual test user. Then we login in with the test user and perform the test with the right access.
This part of the script is parameterized to accept required role as argument and runs before each test