-
Notifications
You must be signed in to change notification settings - Fork 354
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
test: user-page-models #9084
test: user-page-models #9084
Conversation
✅ Deploy Preview for determined-ui ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #9084 +/- ##
==========================================
- Coverage 47.07% 40.30% -6.78%
==========================================
Files 1155 848 -307
Lines 142400 103887 -38513
Branches 2421 2444 +23
==========================================
- Hits 67034 41869 -25165
+ Misses 75176 61813 -13363
- Partials 190 205 +15
Flags with carried forward coverage won't be shown. Click here to find out more.
|
2b40ecf
to
1847fbb
Compare
1847fbb
to
cddd7a3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, mostly style comments/questions
data-testid="username" | ||
disabled={!!user} | ||
maxLength={128} | ||
placeholder="Username" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Place holder changed here as well. Was that intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah the space was bugging me. It was intentional if reviewers are okay with it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's not introduce copy changes in the testing pr.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*/ | ||
get root(): BasePage { | ||
let root: parentTypes = this._parent; | ||
for (; !(root instanceof BasePage); root = root._parent) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I prefer while
here. Just feels better to me than having 2 empty fields
for (; !(root instanceof BasePage); root = root._parent) { | |
while(!(root instanceof BasePage)){ | |
root = root._parent | |
} |
debugComponentVisible(component: BaseComponent): void { | ||
const componentTree: parentTypes[] = []; | ||
let root: parentTypes = component; | ||
for (; !(root instanceof BasePage); root = root._parent) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same style comment as the other for
vs. while
line. If you really want to get fancy you could make an iterator function for this that runs the same operation on each element, but probably overkill.
debugComponentVisible(component: BaseComponent): void { | ||
const componentTree: parentTypes[] = []; | ||
let root: parentTypes = component; | ||
for (; !(root instanceof BasePage); root = root._parent) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the underscore in _parent
implies private/protected to me, so to access it outside the inheritance hierarchy, I think we either should have a getter for this field, or remove the underscore and allow it to be public. I think I prefer the getter option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do you prefer the getter? it's already readonly, so i don't think we need to hide the attribute. i'd rather remove the underscore
* @param {string} [obj.selector] - Used instead of `defaultSelector` | ||
*/ | ||
export class AddUsersToGroupsModal extends Modal { | ||
static override defaultSelector: string = Modal.defaultSelector; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we actually have to override this if we are just using the the parent selector?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. another reason to switch to instance property
await userManagementPage.createUserModal.username.pwLocator.fill(username); | ||
await userManagementPage.createUserModal.footer.submit.pwLocator.click(); | ||
const newIDs = await userManagementPage.table.table.newRowKeys(oldIDs); | ||
expect(newIDs, `newids ${newIDs}, oldids ${oldIDs}`).toHaveLength(1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we get the ID from the username? If the username has a uuid do we even need the internal ID for the test? We could just find the row with the username.
readonly username: BaseComponent = new BaseComponent({ parent: this.form, selector: "input[data-testid='username']" }); | ||
readonly password: BaseComponent = new BaseComponent({ parent: this.form, selector: "input[data-testid='password']" }); | ||
readonly submit: BaseComponent = new BaseComponent({ parent: this.form, selector: "button[data-testid='submit']" }); | ||
readonly #form: BaseComponent = new BaseComponent({ parent: this, selector: `form` }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For my own edification, why did this switch to having #
starting the variable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#
is for private.
I was thinking it's useful for the hierarchy, but we never .click() or .fill() it's pwlocator.
webui/react/src/e2e/models/components/Table/InteractiveTable.ts
Outdated
Show resolved
Hide resolved
webui/react/src/e2e/models/components/Table/InteractiveTable.ts
Outdated
Show resolved
Hide resolved
* @param {string} value - value of the row attribute | ||
*/ | ||
return (value: string) => { | ||
// TODO default selector should be instance property to make this easier. We want RowType.defaultSelector |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you talk a little about how making the default selector an instance property would make this easier?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, here's the change
#9096
the problem is that we want to use selector: RowType.defaultSelector +
[${key}="${value}"],
, but TS doesn't know about any static elements on the generic class RowType
. I put Row.defaultSelector
here to make the compiler happy, and it works for now.
class UserRow extends Row {
static override defaultSelector: string = Row.defaultSelector;
With the instance property, the lines here change to
return new this.#rowType({
attachment: `[${key}="${value}"]`,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's fixable -- the issue you're running into is that the type of a class is its instance type in typescript -- when referring to the class itself, you want the typeof
the class:
class Coordinates {
static memo = "hello" as const
x = 0
y = 0
}
const c: Coordinates = new Coordinates();
const s: (typeof Coordinates)['memo'] = "hello"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the error message is saying that you're using the type where you want to use a value -- shouldn't it be this.rowType.defaultSelector
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and here's the implementation from basecomponent.ts
export abstract class NamedComponent extends BaseComponent {
constructor({ parent, selector }: { parent: parentTypes; selector: string }) {
super({ parent, selector });
requireStaticArgs(this.constructor, ['defaultSelector']);
}
}
// TODO remove this for instance properties instead. static has been difficult to work with
export function requireStaticArgs<T extends object>(obj: T, requiredProperties: string[]): void {
requiredProperties.forEach((requiredProp) => {
if (!Object.hasOwn(obj, requiredProp)) {
throw new Error(`${obj} must declare a static ${requiredProp}!`);
}
});
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's because of the RowTypeGeneric
-- you don't need that with the typeof
because it knows the type of the constructor already and changing the type of the constructor would break the extension
Co-authored-by: Ashton G. <ashton.galloway@hpe.com>
Co-authored-by: Ashton G. <ashton.galloway@hpe.com>
await expect(page).toHaveURL(userManagementPage.url); | ||
}); | ||
|
||
// test('Users table count matches admin page users tab', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
delete comment before merge
Description
This should be most of the page model changes that come with the user tests. This includes the nav sidebar and interactive tables, and all the other pieces of the user admin page.
There's also a test pattern here where we begin test setup with creating a user, and teardown by deactivating it, all through the UI. Unfortunately, I couldn't find a way to delete test users. We would want to consider running teardown at test setup time as well, or maybe a separate reaper script. Neither are happening at this moment, so this would be a good place to begin that discussion.
Test Plan
Commentary (optional)
Checklist
docs/release-notes/
.See Release Note for details.
Ticket
INFENG-455