Skip to content

Commit

Permalink
Add UI table to regression and functionality tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristianZaccaria committed Sep 25, 2024
1 parent a8ba6f7 commit 4832462
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 13 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/ui_notebooks_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ jobs:
jq -r 'del(.cells[] | select(.source[] | contains("Create authentication object for user permissions")))' 3_widget_example.ipynb > 3_widget_example.ipynb.tmp && mv 3_widget_example.ipynb.tmp 3_widget_example.ipynb
jq -r 'del(.cells[] | select(.source[] | contains("auth.logout()")))' 3_widget_example.ipynb > 3_widget_example.ipynb.tmp && mv 3_widget_example.ipynb.tmp 3_widget_example.ipynb
# Set explicit namespace as SDK need it (currently) to resolve local queues
sed -i "s/head_memory_limits=2,/head_memory_limits=2, namespace='default',/" 3_widget_example.ipynb
sed -i "s/head_memory_limits=2,/head_memory_limits=2, namespace='default', image="quay.io/modh/ray:2.35.0-py39-cu121",/" 3_widget_example.ipynb
sed -i "s/view_clusters()/view_clusters('default')/" 3_widget_example.ipynb
working-directory: demo-notebooks/guided-demos

- name: Run UI notebook tests
Expand Down
18 changes: 14 additions & 4 deletions demo-notebooks/guided-demos/3_widget_example.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"outputs": [],
"source": [
"# Import pieces from codeflare-sdk\n",
"from codeflare_sdk import Cluster, ClusterConfiguration, TokenAuthentication"
"from codeflare_sdk import Cluster, ClusterConfiguration, TokenAuthentication, view_clusters"
]
},
{
Expand Down Expand Up @@ -61,7 +61,7 @@
"# Create and configure our cluster object\n",
"# The SDK will try to find the name of your default local queue based on the annotation \"kueue.x-k8s.io/default-queue\": \"true\" unless you specify the local queue manually below\n",
"cluster = Cluster(ClusterConfiguration(\n",
" name='raytest', \n",
" name='raytest',\n",
" head_cpu_requests='500m',\n",
" head_cpu_limits='500m',\n",
" head_memory_requests=2,\n",
Expand All @@ -73,12 +73,22 @@
" worker_cpu_limits=1,\n",
" worker_memory_requests=2,\n",
" worker_memory_limits=2,\n",
" # image=\"\", # Optional Field \n",
" write_to_file=False, # When enabled Ray Cluster yaml files are written to /HOME/.codeflare/resources \n",
" # image=\"\", # Optional Field\n",
" write_to_file=False, # When enabled Ray Cluster yaml files are written to /HOME/.codeflare/resources\n",
" # local_queue=\"local-queue-name\" # Specify the local queue manually\n",
"))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3de6403c",
"metadata": {},
"outputs": [],
"source": [
"view_clusters()"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down
58 changes: 50 additions & 8 deletions ui-tests/tests/widget_notebook_example.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ test.describe("Visual Regression", () => {
tmpPath,
}) => {
const notebook = "3_widget_example.ipynb";
const namespace = 'default';
await page.notebook.openByPath(`${tmpPath}/${notebook}`);
await page.notebook.activate(notebook);

const captures: (Buffer | null)[] = []; // Array to store cell screenshots
const cellCount = await page.notebook.getCellCount();
console.log(`Cell count: ${cellCount}`);

// Run all cells and capture their screenshots
await page.notebook.runCellByCell({
Expand All @@ -59,25 +61,27 @@ test.describe("Visual Regression", () => {
}
}

const widgetCellIndex = 3;
// At this point, all cells have been ran, and their screenshots have been captured.
// We now interact with the widgets in the notebook.
const upDownWidgetCellIndex = 3; // 4 on OpenShift

await waitForWidget(page, widgetCellIndex, 'input[type="checkbox"]');
await waitForWidget(page, widgetCellIndex, 'button:has-text("Cluster Down")');
await waitForWidget(page, widgetCellIndex, 'button:has-text("Cluster Up")');
await waitForWidget(page, upDownWidgetCellIndex, 'input[type="checkbox"]');
await waitForWidget(page, upDownWidgetCellIndex, 'button:has-text("Cluster Down")');
await waitForWidget(page, upDownWidgetCellIndex, 'button:has-text("Cluster Up")');

await interactWithWidget(page, widgetCellIndex, 'input[type="checkbox"]', async (checkbox) => {
await interactWithWidget(page, upDownWidgetCellIndex, 'input[type="checkbox"]', async (checkbox) => {
await checkbox.click();
const isChecked = await checkbox.isChecked();
expect(isChecked).toBe(true);
});

await interactWithWidget(page, widgetCellIndex, 'button:has-text("Cluster Down")', async (button) => {
await interactWithWidget(page, upDownWidgetCellIndex, 'button:has-text("Cluster Down")', async (button) => {
await button.click();
const clusterDownMessage = await page.waitForSelector('text=No instances found, nothing to be done.', { timeout: 5000 });
expect(clusterDownMessage).not.toBeNull();
});

await interactWithWidget(page, widgetCellIndex, 'button:has-text("Cluster Up")', async (button) => {
await interactWithWidget(page, upDownWidgetCellIndex, 'button:has-text("Cluster Up")', async (button) => {
await button.click();

const successMessage = await page.waitForSelector('text=Ray Cluster: \'raytest\' has successfully been created', { timeout: 10000 });
Expand All @@ -95,13 +99,51 @@ test.describe("Visual Regression", () => {

await runPreviousCell(page, cellCount, '(<CodeFlareClusterStatus.READY: 1>, True)');

await interactWithWidget(page, widgetCellIndex, 'button:has-text("Cluster Down")', async (button) => {
await interactWithWidget(page, upDownWidgetCellIndex, 'button:has-text("Cluster Down")', async (button) => {
await button.click();
const clusterDownMessage = await page.waitForSelector('text=Ray Cluster: \'raytest\' has successfully been deleted', { timeout: 5000 });
expect(clusterDownMessage).not.toBeNull();
});

await runPreviousCell(page, cellCount, '(<CodeFlareClusterStatus.UNKNOWN: 6>, False)');

// view_clusters table with buttons
await interactWithWidget(page, upDownWidgetCellIndex, 'input[type="checkbox"]', async (checkbox) => {
await checkbox.click();
const isChecked = await checkbox.isChecked();
expect(isChecked).toBe(false);
});

await interactWithWidget(page, upDownWidgetCellIndex, 'button:has-text("Cluster Up")', async (button) => {
await button.click();
const successMessage = await page.waitForSelector('text=Ray Cluster: \'raytest\' has successfully been created', { timeout: 10000 });
expect(successMessage).not.toBeNull();
});

const viewClustersCellIndex = 4; // 5 on OpenShift
await page.notebook.runCell(cellCount - 2, true);
await interactWithWidget(page, viewClustersCellIndex, 'button:has-text("Open Ray Dashboard")', async (button) => {
await button.click();
const successMessage = await page.waitForSelector('text=Opening Ray Dashboard for raytest cluster', { timeout: 5000 });
expect(successMessage).not.toBeNull();
});

await interactWithWidget(page, viewClustersCellIndex, 'button:has-text("View Jobs")', async (button) => {
await button.click();
const successMessage = await page.waitForSelector('text=Opening Ray Jobs Dashboard for raytest cluster', { timeout: 5000 });
expect(successMessage).not.toBeNull();
});

await interactWithWidget(page, viewClustersCellIndex, 'button:has-text("Delete Cluster")', async (button) => {
await button.click();

const noClustersMessage = await page.waitForSelector(`text=No clusters found in the ${namespace} namespace.`, { timeout: 5000 });
expect(noClustersMessage).not.toBeNull();
const successMessage = await page.waitForSelector(`text=Cluster raytest in the ${namespace} namespace was deleted successfully.`, { timeout: 5000 });
expect(successMessage).not.toBeNull();
});

await runPreviousCell(page, cellCount, '(<CodeFlareClusterStatus.UNKNOWN: 6>, False)');
});
});

Expand Down

0 comments on commit 4832462

Please sign in to comment.