Skip to content

Commit 2d791b4

Browse files
Ygnasopenshift-merge-bot[bot]
authored andcommitted
UI visual regression testing to cover UI widgets visibility
1 parent c6ed1a1 commit 2d791b4

15 files changed

+4261
-2
lines changed
+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
name: UI notebooks tests
2+
3+
on:
4+
pull_request:
5+
types: [labeled]
6+
7+
concurrency:
8+
group: ${{ github.head_ref }}-${{ github.workflow }}
9+
cancel-in-progress: true
10+
11+
env:
12+
CODEFLARE_OPERATOR_IMG: "quay.io/project-codeflare/codeflare-operator:dev"
13+
14+
jobs:
15+
verify-3_widget_example:
16+
if: ${{ github.event.label.name == 'test-guided-notebooks' || github.event.label.name == 'test-ui-notebooks'}}
17+
runs-on: ubuntu-20.04-4core
18+
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
with:
23+
submodules: recursive
24+
25+
- name: Checkout common repo code
26+
uses: actions/checkout@v4
27+
with:
28+
repository: "project-codeflare/codeflare-common"
29+
ref: "main"
30+
path: "common"
31+
32+
- name: Checkout CodeFlare operator repository
33+
uses: actions/checkout@v4
34+
with:
35+
repository: project-codeflare/codeflare-operator
36+
path: codeflare-operator
37+
38+
- name: Set Go
39+
uses: actions/setup-go@v5
40+
with:
41+
go-version-file: "./codeflare-operator/go.mod"
42+
cache-dependency-path: "./codeflare-operator/go.sum"
43+
44+
- name: Set up gotestfmt
45+
uses: gotesttools/gotestfmt-action@v2
46+
with:
47+
token: ${{ secrets.GITHUB_TOKEN }}
48+
49+
- name: Set up specific Python version
50+
uses: actions/setup-python@v5
51+
with:
52+
python-version: "3.9"
53+
cache: "pip" # caching pip dependencies
54+
55+
- name: Setup and start KinD cluster
56+
uses: ./common/github-actions/kind
57+
58+
- name: Deploy CodeFlare stack
59+
id: deploy
60+
run: |
61+
cd codeflare-operator
62+
echo Setting up CodeFlare stack
63+
make setup-e2e
64+
echo Deploying CodeFlare operator
65+
make deploy -e IMG="${CODEFLARE_OPERATOR_IMG}" -e ENV="e2e"
66+
kubectl wait --timeout=120s --for=condition=Available=true deployment -n openshift-operators codeflare-operator-manager
67+
cd ..
68+
69+
- name: Setup Guided notebooks execution
70+
run: |
71+
echo "Installing papermill and dependencies..."
72+
pip install poetry ipython ipykernel
73+
poetry config virtualenvs.create false
74+
echo "Installing SDK..."
75+
poetry install --with test,docs
76+
77+
- name: Install Yarn dependencies
78+
run: |
79+
poetry run yarn install
80+
poetry run yarn playwright install chromium
81+
working-directory: ui-tests
82+
83+
- name: Fix 3_widget_example.ipynb notebook for test
84+
run: |
85+
# Remove login/logout cells, as KinD doesn't support authentication using token
86+
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
87+
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
88+
# Set explicit namespace as SDK need it (currently) to resolve local queues
89+
sed -i "s/head_memory_limits=2,/head_memory_limits=2, namespace='default',/" 3_widget_example.ipynb
90+
working-directory: demo-notebooks/guided-demos
91+
92+
- name: Run UI notebook tests
93+
run: |
94+
set -euo pipefail
95+
96+
poetry run yarn test
97+
working-directory: ui-tests
98+
99+
- name: Upload Playwright Test assets
100+
if: always()
101+
uses: actions/upload-artifact@v4
102+
with:
103+
name: ipywidgets-test-assets
104+
path: |
105+
ui-tests/test-results
106+
107+
- name: Upload Playwright Test report
108+
if: always()
109+
uses: actions/upload-artifact@v4
110+
with:
111+
name: ipywidgets-test-report
112+
path: |
113+
ui-tests/playwright-report

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,7 @@ Pipfile.lock
88
build/
99
tls-cluster-namespace
1010
quicktest.yaml
11+
node_modules
12+
.DS_Store
13+
ui-tests/playwright-report
14+
ui-tests/test-results
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "8d4a42f6",
6+
"metadata": {},
7+
"source": [
8+
"In this notebook, we will go through the basics of using the SDK to:\n",
9+
" - Spin up a Ray cluster with our desired resources\n",
10+
" - View the status and specs of our Ray cluster\n",
11+
" - Take down the Ray cluster when finished"
12+
]
13+
},
14+
{
15+
"cell_type": "code",
16+
"execution_count": null,
17+
"id": "b55bc3ea-4ce3-49bf-bb1f-e209de8ca47a",
18+
"metadata": {},
19+
"outputs": [],
20+
"source": [
21+
"# Import pieces from codeflare-sdk\n",
22+
"from codeflare_sdk import Cluster, ClusterConfiguration, TokenAuthentication"
23+
]
24+
},
25+
{
26+
"cell_type": "code",
27+
"execution_count": null,
28+
"id": "614daa0c",
29+
"metadata": {},
30+
"outputs": [],
31+
"source": [
32+
"# Create authentication object for user permissions\n",
33+
"# IF unused, SDK will automatically check for default kubeconfig, then in-cluster config\n",
34+
"# KubeConfigFileAuthentication can also be used to specify kubeconfig path manually\n",
35+
"auth = TokenAuthentication(\n",
36+
" token = \"XXXXX\",\n",
37+
" server = \"XXXXX\",\n",
38+
" skip_tls=False\n",
39+
")\n",
40+
"auth.login()"
41+
]
42+
},
43+
{
44+
"cell_type": "markdown",
45+
"id": "bc27f84c",
46+
"metadata": {},
47+
"source": [
48+
"Here, we want to define our cluster by specifying the resources we require for our batch workload. Below, we define our cluster object (which generates a corresponding RayCluster).\n",
49+
"\n",
50+
"NOTE: 'quay.io/modh/ray:2.35.0-py39-cu121' is the default image used by the CodeFlare SDK for creating a RayCluster resource. \n",
51+
"If you have your own Ray image which suits your purposes, specify it in image field to override the default image."
52+
]
53+
},
54+
{
55+
"cell_type": "code",
56+
"execution_count": null,
57+
"id": "0f4bc870-091f-4e11-9642-cba145710159",
58+
"metadata": {},
59+
"outputs": [],
60+
"source": [
61+
"# Create and configure our cluster object\n",
62+
"# 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",
63+
"cluster = Cluster(ClusterConfiguration(\n",
64+
" name='raytest', \n",
65+
" head_cpu_requests='500m',\n",
66+
" head_cpu_limits='500m',\n",
67+
" head_memory_requests=2,\n",
68+
" head_memory_limits=2,\n",
69+
" head_extended_resource_requests={'nvidia.com/gpu':0}, # For GPU enabled workloads set the head_extended_resource_requests and worker_extended_resource_requests\n",
70+
" worker_extended_resource_requests={'nvidia.com/gpu':0},\n",
71+
" num_workers=2,\n",
72+
" worker_cpu_requests='250m',\n",
73+
" worker_cpu_limits=1,\n",
74+
" worker_memory_requests=2,\n",
75+
" worker_memory_limits=2,\n",
76+
" # image=\"\", # Optional Field \n",
77+
" write_to_file=False, # When enabled Ray Cluster yaml files are written to /HOME/.codeflare/resources \n",
78+
" # local_queue=\"local-queue-name\" # Specify the local queue manually\n",
79+
"))"
80+
]
81+
},
82+
{
83+
"cell_type": "code",
84+
"execution_count": null,
85+
"id": "2d8e6ce3",
86+
"metadata": {},
87+
"outputs": [],
88+
"source": [
89+
"cluster.status()"
90+
]
91+
}
92+
],
93+
"metadata": {
94+
"kernelspec": {
95+
"display_name": "Python 3 (ipykernel)",
96+
"language": "python",
97+
"name": "python3"
98+
},
99+
"language_info": {
100+
"codemirror_mode": {
101+
"name": "ipython",
102+
"version": 3
103+
},
104+
"file_extension": ".py",
105+
"mimetype": "text/x-python",
106+
"name": "python",
107+
"nbconvert_exporter": "python",
108+
"pygments_lexer": "ipython3",
109+
"version": "3.9.19"
110+
},
111+
"vscode": {
112+
"interpreter": {
113+
"hash": "f9f85f796d01129d0dd105a088854619f454435301f6ffec2fea96ecbd9be4ac"
114+
}
115+
}
116+
},
117+
"nbformat": 4,
118+
"nbformat_minor": 5
119+
}

0 commit comments

Comments
 (0)