Skip to content

Commit c63b67c

Browse files
committed
copy tokens from UI
1 parent db26f3d commit c63b67c

File tree

2 files changed

+115
-84
lines changed

2 files changed

+115
-84
lines changed

frontend/src/__tests__/cypress/cypress/pages/modelServing.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@ class ModelServingGlobal {
108108
findServingRuntime(name: string) {
109109
return this.findModelsTable().find(`[data-label=Serving Runtime]`).contains(name);
110110
}
111+
112+
findTokenCopyButton(index: number) {
113+
if (index === 0) {
114+
return cy.findAllByTestId('token-secret').findAllByRole('button').eq(0);
115+
}
116+
return cy.findAllByTestId('token-secret').eq(index).findAllByRole('button').eq(0);
117+
}
111118
}
112119

113120
class ServingRuntimeGroup extends Contextual<HTMLElement> {}
@@ -243,7 +250,7 @@ class InferenceServiceModal extends ServingModal {
243250
return this.find().findByTestId('service-account-form-name');
244251
}
245252

246-
findSpecificServiceAccountNameInput(index: number) {
253+
findServiceAccountIndex(index: number) {
247254
return this.find().findAllByTestId('service-account-form-name').eq(index);
248255
}
249256

frontend/src/__tests__/cypress/cypress/tests/e2e/dataScienceProjects/models/testModelTokenAuth.cy.ts

Lines changed: 107 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { retryableBefore } from '#~/__tests__/cypress/cypress/utils/retryableHoo
1111
import { generateTestUUID } from '#~/__tests__/cypress/cypress/utils/uuidGenerator';
1212
import {
1313
checkInferenceServiceState,
14-
getModelExternalToken,
1514
modelExternalTester,
1615
provisionProjectForModelServing,
1716
verifyModelExternalToken,
@@ -55,89 +54,114 @@ describe('A model can be deployed with token auth', () => {
5554
deleteOpenShiftProject(projectName, { wait: true, ignoreNotFound: true, timeout: 300000 });
5655
});
5756

58-
it('Verify that a model can be deployed with token auth', () => {
59-
cy.log('Model Name:', modelName);
60-
cy.step(`Log into the application with ${HTPASSWD_CLUSTER_ADMIN_USER.USERNAME}`);
61-
cy.visitWithLogin('/', HTPASSWD_CLUSTER_ADMIN_USER);
62-
63-
// Project navigation
64-
cy.step(`Navigate to the Project list tab and search for ${projectName}`);
65-
projectListPage.navigate();
66-
projectListPage.filterProjectByName(projectName);
67-
projectListPage.findProjectLink(projectName).click();
68-
69-
// Navigate to Model Serving tab and Deploy a model
70-
cy.step('Navigate to Model Serving and click to Deploy a model');
71-
projectDetails.findSectionTab('model-server').click();
72-
modelServingGlobal.findSingleServingModelButton().click();
73-
modelServingGlobal.findDeployModelButton().click();
74-
75-
// Launch a model
76-
cy.step('Launch a Single Serving Model using Openvino');
77-
inferenceServiceModal.findModelNameInput().type(testData.singleModelName);
78-
inferenceServiceModal.findServingRuntimeTemplateSearchSelector().click();
79-
inferenceServiceModal.findGlobalScopedTemplateOption('OpenVINO Model Server').click();
80-
inferenceServiceModal.findModelFrameworkSelect().click();
81-
inferenceServiceModal.findOpenVinoIROpSet13().click();
82-
83-
// Enable Model access through an external route
84-
cy.step('Enable Model access through an external route');
85-
inferenceServiceModal.findDeployedModelRouteCheckbox().click();
86-
inferenceServiceModal.findDeployedModelRouteCheckbox().should('be.checked');
87-
inferenceServiceModal.findSpecificServiceAccountNameInput(0).clear();
88-
inferenceServiceModal.findSpecificServiceAccountNameInput(0).type('secret');
89-
inferenceServiceModal.findAddServiceAccountButton().click();
90-
inferenceServiceModal.findSpecificServiceAccountNameInput(1).clear();
91-
inferenceServiceModal.findSpecificServiceAccountNameInput(1).type('secret2');
92-
inferenceServiceModal.findLocationPathInput().type(modelFilePath);
93-
inferenceServiceModal.findSubmitButton().click();
94-
inferenceServiceModal.shouldBeOpen(false);
95-
96-
// Verify the model created
97-
cy.step('Verify that the Model is running');
98-
checkInferenceServiceState(testData.singleModelName, projectName, {
99-
checkReady: true,
100-
checkLatestDeploymentReady: true,
101-
});
102-
103-
// Verify the model is not accessible without a token
104-
cy.step('Verify the model is not accessible without a token');
105-
modelExternalTester(modelName, projectName).then(({ response }) => {
106-
expect(response.status).to.equal(401);
107-
});
108-
109-
// Verify the model is accessible with a token
110-
cy.step('Verify the model is accessible with a token');
111-
getModelExternalToken(projectName, 'secret', modelName)
112-
.then((token) => verifyModelExternalToken(modelName, projectName, token))
113-
.then((response) => {
114-
expect(response.status).to.equal(200);
57+
it(
58+
'Verify that a model can be deployed with token auth',
59+
{ tags: ['@Smoke', '@SmokeSet3', '@Dashboard', '@ModelServing'] },
60+
() => {
61+
cy.log('Model Name:', modelName);
62+
cy.step(`Log into the application with ${HTPASSWD_CLUSTER_ADMIN_USER.USERNAME}`);
63+
cy.visitWithLogin('/', HTPASSWD_CLUSTER_ADMIN_USER);
64+
65+
// Project navigation
66+
cy.step(`Navigate to the Project list tab and search for ${projectName}`);
67+
projectListPage.navigate();
68+
projectListPage.filterProjectByName(projectName);
69+
projectListPage.findProjectLink(projectName).click();
70+
71+
// Navigate to Model Serving tab and Deploy a model
72+
cy.step('Navigate to Model Serving and click to Deploy a model');
73+
projectDetails.findSectionTab('model-server').click();
74+
modelServingGlobal.findSingleServingModelButton().click();
75+
modelServingGlobal.findDeployModelButton().click();
76+
77+
// Launch a model
78+
cy.step('Launch a Single Serving Model using Openvino');
79+
inferenceServiceModal.findModelNameInput().type(testData.singleModelName);
80+
inferenceServiceModal.findServingRuntimeTemplateSearchSelector().click();
81+
inferenceServiceModal.findGlobalScopedTemplateOption('OpenVINO Model Server').click();
82+
inferenceServiceModal.findModelFrameworkSelect().click();
83+
inferenceServiceModal.findOpenVinoIROpSet13().click();
84+
85+
// Enable Model access through an external route
86+
cy.step('Enable Model access through an external route');
87+
inferenceServiceModal.findDeployedModelRouteCheckbox().click();
88+
inferenceServiceModal.findDeployedModelRouteCheckbox().should('be.checked');
89+
inferenceServiceModal.findServiceAccountIndex(0).clear();
90+
inferenceServiceModal.findServiceAccountIndex(0).type('secret');
91+
inferenceServiceModal.findAddServiceAccountButton().click();
92+
inferenceServiceModal.findServiceAccountIndex(1).clear();
93+
inferenceServiceModal.findServiceAccountIndex(1).type('secret2');
94+
inferenceServiceModal.findLocationPathInput().type(modelFilePath);
95+
inferenceServiceModal.findSubmitButton().click();
96+
inferenceServiceModal.shouldBeOpen(false);
97+
98+
// Verify the model created
99+
cy.step('Verify that the Model is running');
100+
checkInferenceServiceState(testData.singleModelName, projectName, {
101+
checkReady: true,
102+
checkLatestDeploymentReady: true,
115103
});
116-
getModelExternalToken(projectName, 'secret2', modelName)
117-
.then((token) => verifyModelExternalToken(modelName, projectName, token))
118-
.then((response) => {
119-
expect(response.status).to.equal(200);
104+
105+
// Verify the model is not accessible without a token
106+
cy.step('Verify the model is not accessible without a token');
107+
modelExternalTester(modelName, projectName).then(({ response }) => {
108+
expect(response.status).to.equal(401);
120109
});
121110

122-
// Remove the token
123-
cy.step('Remove the token');
124-
modelServingSection
125-
.getKServeRow(testData.singleModelName)
126-
.find()
127-
.findKebabAction('Edit')
128-
.click();
129-
// Check the service accounts are showing up in the UI
130-
kserveModalEdit.findSpecificServiceAccountNameInput(0).should('have.value', 'secret');
131-
kserveModalEdit.findSpecificServiceAccountNameInput(1).should('have.value', 'secret2');
132-
kserveModalEdit.findTokenAuthenticationCheckbox().click();
133-
kserveModalEdit.findTokenAuthenticationCheckbox().should('not.be.checked');
134-
kserveModalEdit.findSubmitButton().click();
135-
kserveModalEdit.shouldBeOpen(false);
136-
137-
// Verify the model is accessible without a token
138-
cy.step('Verify the model is accessible without a token');
139-
verifyModelExternalToken(modelName, projectName).then((response) => {
140-
expect(response.status).to.equal(200);
141-
});
142-
});
111+
// Get the tokens from the UI
112+
cy.step('Get the tokens from the UI');
113+
const kserveRow = modelServingSection.getKServeRow(testData.singleModelName);
114+
kserveRow.findToggleButton().click();
115+
116+
//cy.window({ log: false }).then((win) => win.focus());
117+
118+
cy.window().then((win) => {
119+
const copied: string[] = [];
120+
cy.wrap(copied).as('copiedTokens');
121+
122+
cy.stub(win.navigator.clipboard, 'writeText').callsFake((text: string) => {
123+
copied.push(text);
124+
return Promise.resolve();
125+
});
126+
});
127+
128+
// Click the two copy buttons
129+
modelServingGlobal.findTokenCopyButton(0).click();
130+
modelServingGlobal.findTokenCopyButton(1).click();
131+
132+
// Use the copied tokens
133+
cy.get<string[]>('@copiedTokens')
134+
.should('have.length.at.least', 2)
135+
.then((tokens) => {
136+
const [token1, token2] = tokens;
137+
verifyModelExternalToken(modelName, projectName, token1).then((r) =>
138+
expect(r.status).to.equal(200),
139+
);
140+
verifyModelExternalToken(modelName, projectName, token2).then((r) =>
141+
expect(r.status).to.equal(200),
142+
);
143+
});
144+
145+
// Remove the token
146+
cy.step('Remove the token');
147+
modelServingSection
148+
.getKServeRow(testData.singleModelName)
149+
.find()
150+
.findKebabAction('Edit')
151+
.click();
152+
// Check the service accounts are showing up in the UI
153+
kserveModalEdit.findServiceAccountIndex(0).should('have.value', 'secret');
154+
kserveModalEdit.findServiceAccountIndex(1).should('have.value', 'secret2');
155+
kserveModalEdit.findTokenAuthenticationCheckbox().click();
156+
kserveModalEdit.findTokenAuthenticationCheckbox().should('not.be.checked');
157+
kserveModalEdit.findSubmitButton().click();
158+
kserveModalEdit.shouldBeOpen(false);
159+
160+
// Verify the model is accessible without a token
161+
cy.step('Verify the model is accessible without a token');
162+
verifyModelExternalToken(modelName, projectName).then((response) => {
163+
expect(response.status).to.equal(200);
164+
});
165+
},
166+
);
143167
});

0 commit comments

Comments
 (0)