Skip to content

Commit

Permalink
feat: PR check GitHub Action
Browse files Browse the repository at this point in the history
Signed-off-by: mdolhalo <[email protected]>
  • Loading branch information
mdolhalo committed Jul 25, 2023
1 parent 4dc1021 commit 9a47941
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 133 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/contributing-repositories-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#

# Eclipse Che workflow for checking repository list in CONTRIBUTING.md file
name: CI
name: Check repository list in CONTRIBUTING.md file

# Trigger the workflow on push or pull request
on:
Expand Down
25 changes: 1 addition & 24 deletions .github/workflows/next-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# SPDX-License-Identifier: EPL-2.0
#

name: build-next
name: Build and push Next Che E2E image to quay.io

on:
workflow_dispatch:
Expand All @@ -21,18 +21,6 @@ jobs:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Cache local Maven repository
uses: actions/cache@v3
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
distribution: 'adopt'
java-version: '11'
- name: Login to docker.io
uses: docker/login-action@v2
with:
Expand All @@ -59,14 +47,3 @@ jobs:
run: |
docker push quay.io/eclipse/che-e2e:next
docker push quay.io/eclipse/che-e2e:${{ steps.build.outputs.short_sha1 }}
- name: Create failure MM message
if: ${{ failure() }}
run: |
echo "{\"text\":\":no_entry_sign: Next Che E2E build has failed: https://github.com/eclipse/che/actions/workflows/next-build.yml\"}" > mattermost.json
- name: Send MM message
if: ${{ failure() }}
uses: mattermost/[email protected]
env:
MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_WEBHOOK_URL }}
MATTERMOST_CHANNEL: eclipse-che-ci
MATTERMOST_USERNAME: che-bot
174 changes: 174 additions & 0 deletions .github/workflows/pr-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
#
# Copyright (c) 2021-2023 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#

#This GitHub Action runs Empty Workspace API test, build Che e2e test container and runs Empty Workspace UI test
#on Che Next deployed on minikube;
#Empty Workspace tests were chosen because of low resource of VM (7RAM, 2CPU, 14Gb disk);
#other cases returned "Insufficient cpu" error

name: Empty Workspace test suite on minikube

# Trigger the workflow on pull request
on:
workflow_dispatch:
pull_request:
branches:
- main
- 7.**.x
paths:
- 'tests/e2e/**'
- '.github/workflows/pr-check.yml'
env:
LOCAL_TEST_DIR: /tmp

jobs:
pr-check:
runs-on: ubuntu-22.04

steps:
- name: Git checkout
uses: actions/checkout@v2

- name: Branch name
run: |
echo running on PR ${GITHUB_REF}, branch - ${GITHUB_HEAD_REF}
echo "pr_number=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }')" >> "$GITHUB_ENV"
- name: Configuring nodejs 16.x version
uses: actions/setup-node@v3
with:
node-version: '16'

- name: Pull Che-Code Docker image
run: |
#
# pull che-code:next docker image
#
docker pull quay.io/che-incubator/che-code:next
- name: Start minikube
id: run-minikube
uses: che-incubator/setup-minikube-action@next
with:
minikube-version: v1.23.2

- name: Install chectl
run: bash <(curl -sL https://www.eclipse.org/che/chectl/) --channel=next

- name: Deploy Che
run: |
#
# load Che-Code image into minikube
#
minikube image load quay.io/che-incubator/che-code:next
minikube image list
# get patch file to set up resources
wget https://raw.githubusercontent.com/che-incubator/che-code/main/build/test/github-minikube-checluster-patch.yaml -P /tmp
#
# deploy Che
#
chectl server:deploy \
--batch \
--platform minikube \
--k8spodwaittimeout=120000 \
--k8spodreadytimeout=120000 \
--che-operator-cr-patch-yaml "/tmp/github-minikube-checluster-patch.yaml"
#
# apply patch
#
kubectl patch devworkspaceoperatorconfigs \
-n eclipse-che devworkspace-config \
--patch '{"config": {"workspace": {"imagePullPolicy": "IfNotPresent"}}}' \
--type merge
- name: Pull Universal Base Image
run: |
minikube image pull quay.io/devfile/universal-developer-image:ubi8-latest
- name: Run Empty Workspace API test
run: |
cd tests/e2e
npm ci
export TS_PLATFORM=kubernetes &&
export TS_API_TEST_KUBERNETES_COMMAND_LINE_TOOL=kubectl &&
export TS_SELENIUM_VALUE_OPENSHIFT_OAUTH=false &&
export TS_SELENIUM_BASE_URL=https://$(kubectl get ingress che -n eclipse-che -o jsonpath='{.spec.rules[0].host}') &&
export NODE_TLS_REJECT_UNAUTHORIZED=0 &&
export TS_SELENIUM_LOG_LEVEL=TRACE &&
export TS_SELENIUM_DEFAULT_ATTEMPTS=2 &&
export USERSTORY=EmptyWorkspaceAPI &&
export TS_API_TEST_UDI_IMAGE=quay.io/devfile/universal-developer-image:ubi8-latest &&
npm run driver-less-test
- name: Build E2E test docker image
run: |
set -xe
cd tests/e2e
docker build -t quay.io/eclipse/che-e2e:"${{ env.pr_number }}" -f build/dockerfiles/Dockerfile .
- name: Run Empty Workspace UI test from che-e2e container
run: |
docker run \
--shm-size=2048m \
-p 5920:5920 \
--network="host" \
-e TS_PLATFORM=kubernetes \
-e TS_API_TEST_KUBERNETES_COMMAND_LINE_TOOL=kubectl \
-e [email protected] \
-e TS_SELENIUM_K8S_PASSWORD=admin \
-e TS_SELENIUM_VALUE_OPENSHIFT_OAUTH=false \
-e TS_SELENIUM_BASE_URL=https://$(kubectl get ingress che -n eclipse-che -o jsonpath='{.spec.rules[0].host}') \
-e TS_SELENIUM_LOAD_PAGE_TIMEOUT=60000 \
-e TS_SELENIUM_START_WORKSPACE_TIMEOUT=120000 \
-e TS_COMMON_DASHBOARD_WAIT_TIMEOUT=30000 \
-e NODE_TLS_REJECT_UNAUTHORIZED=0 \
-e DELETE_WORKSPACE_ON_FAILED_TEST=true \
-e VIDEO_RECORDING=true \
-e TS_SELENIUM_LOG_LEVEL=TRACE \
-e TS_SELENIUM_DEFAULT_ATTEMPTS=2 \
-v ${LOCAL_TEST_DIR}/tests/e2e/report:/tmp/e2e/report:Z \
-v ${LOCAL_TEST_DIR}/tests/e2e/video:/tmp/ffmpeg_report:Z \
-e TEST_SUITE=test \
-e USERSTORY=EmptyWorkspace \
quay.io/eclipse/che-e2e:"${{ env.pr_number }}"
- name: Bump logs
if: always()
run: |
NS=admin-che
TARGET_DIR="/tmp/pr-check-artifacts/${NS}-info"
mkdir -p "$TARGET_DIR"
for POD in $(kubectl get pods -o name -n ${NS}); do
for CONTAINER in $(kubectl get -n ${NS} ${POD} -o jsonpath="{.spec.containers[*].name}"); do
echo "[INFO] Downloading logs $POD/$CONTAINER in $NS"
# container name includes `pod/` prefix. remove it
LOGS_FILE=$TARGET_DIR/$(echo ${POD}-${CONTAINER}.log | sed 's|pod/||g')
kubectl logs ${POD} -c ${CONTAINER} -n ${NS} > $LOGS_FILE || true
done
done
echo "[INFO] Bumping events in namespace ${NS}"
kubectl get events -n $NS > $TARGET_DIR/events.log || true
- name: Store e2e artifacts
if: always()
uses: actions/upload-artifact@v3
with:
name: e2e-artifacts
path: /tmp/tests

- name: Store k8s logs
if: always()
uses: actions/upload-artifact@v3
with:
name: k8s-logs
path: /tmp/pr-check-artifacts/admin-che-info
2 changes: 1 addition & 1 deletion .github/workflows/typescript-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# SPDX-License-Identifier: EPL-2.0
#

name: typescript-publish-next
name: Publish Next Che E2E Tests to npmjs

on:
workflow_dispatch:
Expand Down
62 changes: 17 additions & 45 deletions tests/e2e/pageobjects/dashboard/Dashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,17 @@ import { DriverHelper } from '../../utils/DriverHelper';
import { TimeoutConstants } from '../../constants/TimeoutConstants';
import { Workspaces } from './Workspaces';
import { Logger } from '../../utils/Logger';
import { OAuthConstants } from '../../constants/OAuthConstants';
import { BaseTestConstants } from '../../constants/BaseTestConstants';

@injectable()
export class Dashboard {
private static readonly WORKSPACES_BUTTON_XPATH: string = `//div[@id='page-sidebar']//a[contains(text(), 'Workspaces (')]`;
private static readonly CREATE_WORKSPACE_BUTTON_XPATH: string = `//div[@id='page-sidebar']//a[text()='Create Workspace']`;
private static readonly LOADER_PAGE_STEP_TITLES_XPATH: string = '//*[@data-testid="step-title"]';
private static readonly STARTING_PAGE_LOADER_CSS: string = '.main-page-loader';
private static readonly LOADER_ALERT_XPATH: string = '//*[@data-testid="loader-alert"]';
private static readonly LOGOUT_BUTTON_XPATH: string = '//button[text()="Logout"]';

private static getUserDropdownMenuButtonLocator(): By {
Logger.debug(`Dashboard.getUserDropdownMenuButtonLocator: get current user.`);

const currentUser: string = OAuthConstants.TS_SELENIUM_OCP_USERNAME;
Logger.debug(`Dashboard.getUserDropdownMenuButtonLocator: ${currentUser}.`);

return By.xpath(`//*[text()="${currentUser}"]//parent::button`);

}
private static readonly WORKSPACES_BUTTON: By = By.xpath(`//div[@id='page-sidebar']//a[contains(text(), 'Workspaces (')]`);
private static readonly CREATE_WORKSPACE_BUTTON: By = By.xpath(`//div[@id='page-sidebar']//a[text()='Create Workspace']`);
private static readonly LOADER_PAGE_STEP_TITLES: By = By.xpath('//*[@data-testid="step-title"]');
private static readonly STARTING_PAGE_LOADER: By = By.css('.main-page-loader');
private static readonly LOADER_ALERT: By = By.xpath('//*[@data-testid="loader-alert"]');
private static readonly LOGOUT_BUTTON: By = By.xpath('//button[text()="Logout"]');
private static readonly USER_SETTINGS_DROPDOWN: By = By.xpath('//header//button/span[text()!=\'\']//parent::button');

constructor(@inject(CLASSES.DriverHelper) private readonly driverHelper: DriverHelper,
@inject(CLASSES.Workspaces) private readonly workspaces: Workspaces) {
Expand Down Expand Up @@ -82,65 +72,47 @@ export class Dashboard {
async waitPage(timeout: number = TimeoutConstants.TS_SELENIUM_LOAD_PAGE_TIMEOUT): Promise<void> {
Logger.debug('Dashboard.waitPage');

await this.driverHelper.waitVisibility(By.xpath(Dashboard.WORKSPACES_BUTTON_XPATH), timeout);
await this.driverHelper.waitVisibility(By.xpath(Dashboard.CREATE_WORKSPACE_BUTTON_XPATH), timeout);
await this.driverHelper.waitVisibility(Dashboard.WORKSPACES_BUTTON, timeout);
await this.driverHelper.waitVisibility(Dashboard.CREATE_WORKSPACE_BUTTON, timeout);
}

async clickWorkspacesButton(timeout: number = TimeoutConstants.TS_CLICK_DASHBOARD_ITEM_TIMEOUT): Promise<void> {
Logger.debug('Dashboard.clickWorkspacesButton');

await this.driverHelper.waitAndClick(By.xpath(Dashboard.WORKSPACES_BUTTON_XPATH), timeout);
await this.driverHelper.waitAndClick(Dashboard.WORKSPACES_BUTTON, timeout);
}

async clickCreateWorkspaceButton(timeout: number = TimeoutConstants.TS_CLICK_DASHBOARD_ITEM_TIMEOUT): Promise<void> {
Logger.debug('Dashboard.clickCreateWorkspaceButton');

await this.driverHelper.waitAndClick(By.xpath(Dashboard.CREATE_WORKSPACE_BUTTON_XPATH), timeout);
await this.driverHelper.waitAndClick(Dashboard.CREATE_WORKSPACE_BUTTON, timeout);
}

async getLoaderAlert(timeout: number = TimeoutConstants.TS_WAIT_LOADER_PRESENCE_TIMEOUT): Promise<string> {
Logger.debug('Dashboard.getLoaderAlert');

return await this.driverHelper.waitAndGetText(By.xpath(Dashboard.LOADER_ALERT_XPATH), timeout);
return await this.driverHelper.waitAndGetText(Dashboard.LOADER_ALERT, timeout);
}

async waitLoader(timeout: number = TimeoutConstants.TS_WAIT_LOADER_PRESENCE_TIMEOUT): Promise<void> {
Logger.debug('Dashboard.waitLoader');

await this.driverHelper.waitAllPresence(By.xpath(Dashboard.LOADER_PAGE_STEP_TITLES_XPATH), timeout);
}

async waitLoaderDisappearance(timeout: number = TimeoutConstants.TS_WAIT_LOADER_ABSENCE_TIMEOUT): Promise<void> {
Logger.debug('Dashboard.waitLoaderDisappearance');

await this.driverHelper.waitDisappearance(By.xpath(Dashboard.LOADER_PAGE_STEP_TITLES_XPATH), timeout);
}

async waitDisappearanceNavigationMenu(timeout: number = TimeoutConstants.TS_COMMON_DASHBOARD_WAIT_TIMEOUT): Promise<void> {
Logger.debug('Dashboard.waitDisappearanceNavigationMenu');

await this.driverHelper.waitDisappearance(By.id('chenavmenu'), timeout);
await this.driverHelper.waitAllPresence(Dashboard.LOADER_PAGE_STEP_TITLES, timeout);
}

async waitStartingPageLoaderDisappearance(timeout: number = TimeoutConstants.TS_COMMON_DASHBOARD_WAIT_TIMEOUT): Promise<void> {
Logger.debug(`Dashboard.waitStartingPageLoaderDisappearance`);

await this.driverHelper.waitDisappearance(By.css(Dashboard.STARTING_PAGE_LOADER_CSS), timeout);
await this.driverHelper.waitDisappearance(Dashboard.STARTING_PAGE_LOADER, timeout);
await this.driverHelper.wait(TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING);
}

async getRecentWorkspaceName(timeout: number = TimeoutConstants.TS_COMMON_DASHBOARD_WAIT_TIMEOUT): Promise<string> {
Logger.debug(`Dashboard.getRecentWorkspaceName`);

return await this.driverHelper.waitAndGetText(By.css('[data-testid="recent-workspace-item"]'), timeout);
}

async logout(timeout: number = TimeoutConstants.TS_COMMON_DASHBOARD_WAIT_TIMEOUT): Promise<void> {
Logger.debug(`Dashboard.logout`);

await this.openDashboard();
await this.driverHelper.waitAndClick(Dashboard.getUserDropdownMenuButtonLocator(), timeout);
await this.driverHelper.waitAndClick(By.xpath(Dashboard.LOGOUT_BUTTON_XPATH), timeout);
await this.driverHelper.waitDisappearance(Dashboard.getUserDropdownMenuButtonLocator(), timeout);
await this.driverHelper.waitAndClick(Dashboard.USER_SETTINGS_DROPDOWN, timeout);
await this.driverHelper.waitAndClick(Dashboard.LOGOUT_BUTTON, timeout);
await this.driverHelper.waitDisappearance(Dashboard.USER_SETTINGS_DROPDOWN, timeout);
}
}
Loading

0 comments on commit 9a47941

Please sign in to comment.