Skip to content
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

www: Implement e2e tests for React frontend #7045

Merged
merged 10 commits into from
Sep 5, 2023
15 changes: 13 additions & 2 deletions .bbtravis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ matrix:
- env: PYTHON=3.9 TWISTED=latest SQLALCHEMY=latest TESTS=js_build NUM_CPU=2 MEMORY_SIZE=2G
- env: PYTHON=3.9 TWISTED=latest SQLALCHEMY=latest TESTS=js_unit NUM_CPU=2 MEMORY_SIZE=2G
- env: PYTHON=3.9 TWISTED=latest SQLALCHEMY=latest TESTS=smokes NUM_CPU=4 MEMORY_SIZE=4G
- env: PYTHON=3.9 TWISTED=latest SQLALCHEMY=latest TESTS=e2e_react_whl NUM_CPU=2 MEMORY_SIZE=4G
# Re-enable once #7058 is fixed
#- env: PYTHON=3.9 TWISTED=latest SQLALCHEMY=latest TESTS=e2e_react_tgz NUM_CPU=2 MEMORY_SIZE=4G

# include "ci" string into the name of the status that is eventually submitted to Github, so
# that the codecov.io service would wait until this build is finished before creating report.
Expand Down Expand Up @@ -81,7 +84,7 @@ install:
python$PYTHON -m venv /tmp/bbvenv
fi
- /tmp/bbvenv/bin/pip install -U pip wheel
- condition: TESTS not in ("dev_virtualenv", "smokes", "trial_worker")
- condition: TESTS not in ("dev_virtualenv", "smokes", "e2e_react_whl", "e2e_react_tgz", "trial_worker")
cmd: /tmp/bbvenv/bin/pip install -r requirements-ci.txt
- condition: TESTS == "dev_virtualenv"
cmd: /tmp/bbvenv/bin/pip install -r requirements-ci.txt -r requirements-ciworker.txt -r requirements-cidocs.txt
Expand Down Expand Up @@ -216,7 +219,7 @@ script:
make docs-release-spelling

- title: maketarballs
condition: TESTS == "smokes"
condition: TESTS in ("smokes", "e2e_react_whl", "e2e_react_tgz")
cmd: |
export NODE_OPTIONS=--openssl-legacy-provider
export PATH=/tmp/bbvenv/bin/:$PATH
Expand All @@ -236,6 +239,14 @@ script:
export PATH=/tmp/bbvenv/bin/:$PATH
./common/smokedist.sh tar.gz

- title: end to end tests
condition: TESTS == "e2e_react_whl"
cmd: ./common/smokedist-react.sh whl

- title: tarballs end to end tests
condition: TESTS == "e2e_react_tgz"
cmd: ./common/smokedist-react.sh tar.gz

notifications:
email: false

Expand Down
25 changes: 25 additions & 0 deletions common/smokedist-react.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash

if [ -z $1 ]; then
suffixes="whl tar.gz"
else
suffixes=$1
fi
set -e
for suffix in $suffixes
do
VE=sandbox.$suffix
rm -rf $VE
if [ -z "$python" ]; then
virtualenv --python python3 $VE
else
virtualenv --python python$python $VE
fi
. $VE/bin/activate
pip install -U pip
pip install requests flask
pip install dist/buildbot-[0-9]*.$suffix
pip install dist/buildbot?pkg*.$suffix
pip install dist/*.$suffix
smokes-react/run.sh
done
5 changes: 5 additions & 0 deletions smokes-react/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
workdir
/test-results/
/playwright-report/
/playwright/.cache/
139 changes: 139 additions & 0 deletions smokes-react/master.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# -*- python -*-
# ex: set filetype=python:

from buildbot.plugins import *

NUM_BUILDERS = 2

c = BuildmasterConfig = {}

####### WORKERS

c['workers'] = [worker.Worker("example-worker", "pass")]
c['protocols'] = {'pb': {'port': 9989}}


####### CHANGESOURCES

c['change_source'] = []
c['change_source'].append(changes.GitPoller(
'https://github.com/buildbot/hello-world.git', # the buildbot clone of pyflakes
workdir='gitpoller-workdir', branch='master',
pollinterval=300))

####### SCHEDULERS

c['schedulers'] = []
c['schedulers'].append(schedulers.SingleBranchScheduler(
name="all",
change_filter=util.ChangeFilter(branch='master'),
treeStableTimer=None,
builderNames=["runtests" + str(i) for i in range(NUM_BUILDERS)]))

c['schedulers'].append(schedulers.ForceScheduler(
name="force",
builderNames=["runtests", "slowruntests"]))

c['schedulers'].append(schedulers.ForceScheduler(
name="custom",
builderNames=["runtests"],
buttonName="Start Custom Build",
codebases = [util.CodebaseParameter(
codebase='', project=None,
branch=util.ChoiceStringParameter(
name="branch",
label="Branch",
strict=False,
choices=["master", "dev"],
autopopulate={
'master': {
'build_name': 'master',
},
'dev': {
'build_name': 'dev',
}
}
))],
properties=[
util.StringParameter(
name="build_name",
label="Name of the Build release.",
default="")]))

####### BUILDERS

factory = util.BuildFactory()
factory.addStep(steps.Git(repourl='https://github.com/buildbot/hello-world.git',
mode='incremental'))
factory.addStep(steps.ShellCommand(command=["trial", "hello"],
env={"PYTHONPATH": "."}))

slowfactory = util.BuildFactory()
slowfactory.addStep(steps.Git(repourl='https://github.com/buildbot/hello-world.git',
mode='incremental'))
slowfactory.addStep(steps.ShellCommand(command=["trial", "hello"],
env={"PYTHONPATH": "."}))
slowfactory.addStep(steps.ShellCommand(command=["sleep", "10"]))


c['builders'] = []
c['builders'].append(
util.BuilderConfig(name="runtests",
tags=['runt'],
workernames=["example-worker"],
factory=factory))
c['builders'].append(
util.BuilderConfig(name="slowruntests",
tags=['slow', 'runt'],
workernames=["example-worker"],
factory=slowfactory))

for i in range(NUM_BUILDERS):
c['builders'].append(
util.BuilderConfig(name="runtests" + str(i),
tags=[str(i), 'runt'],
workernames=["example-worker"],
factory=factory))


####### PROJECT IDENTITY

c['title'] = "Pyflakes"
c['titleURL'] = "https://launchpad.net/pyflakes"
c['buildbotURL'] = "http://localhost:8011/"

# we're not using the default port so that it would not accidentally conflict
# with any development instances of buildbot on developer machines
c['www'] = {
"port": 8011,
"change_hook_dialects": {'base': True},
"plugins": {
"base_react": {},
"react_waterfall_view": {},
"react_console_view": {},
"react_grid_view": {},
},
"ui_default_config": {'Builders.buildFetchLimit': 201}
}

c['buildbotNetUsageData'] = None

####### DB URL

c['db'] = {
'db_url': "sqlite:///state.sqlite",
}

authz = util.Authz(
allowRules=[
],
roleMatchers=[
util.RolesFromEmails(admins=["my@email.com"])
]
)
auth=util.UserPasswordAuth({'my@email.com': b'mypass'})
c['www']['auth'] = auth
c['www']['authz'] = authz

# in order to share this snippet in the doc, we load mydashboard.py using exec
exec(open("mydashboard.py").read())
65 changes: 65 additions & 0 deletions smokes-react/mydashboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@

import os

from flask import Flask
from flask import render_template

from buildbot.process.results import statusToString

mydashboardapp = Flask('test', root_path=os.path.dirname(__file__))
# this allows to work on the template without having to restart Buildbot
mydashboardapp.config['TEMPLATES_AUTO_RELOAD'] = True


@mydashboardapp.route("/index.html")
def main():
# This code fetches build data from the data api, and give it to the
# template
builders = mydashboardapp.buildbot_api.dataGet("/builders")

builds = mydashboardapp.buildbot_api.dataGet("/builds", limit=20)

# properties are actually not used in the template example, but this is
# how you get more properties
for build in builds:
build['properties'] = mydashboardapp.buildbot_api.dataGet(
("builds", build['buildid'], "properties"))

build['results_text'] = statusToString(build['results'])

graph_data = [
{'x': 1, 'y': 100},
{'x': 2, 'y': 200},
{'x': 3, 'y': 300},
{'x': 4, 'y': 0},
{'x': 5, 'y': 100},
{'x': 6, 'y': 200},
{'x': 7, 'y': 300},
{'x': 8, 'y': 0},
{'x': 9, 'y': 100},
{'x': 10, 'y': 200},
]

# mydashboard.html is a template inside the template directory
return render_template('mydashboard.html', builders=builders, builds=builds,
graph_data=graph_data)


# Here we assume c['www']['plugins'] has already be created earlier.
# Please see the web server documentation to understand how to configure
# the other parts.
# This is a list of dashboards, you can create several
c['www']['plugins']['wsgi_dashboards'] = [
{
'name': 'mydashboard', # as used in URLs
'caption': 'My Dashboard', # Title displayed in the UI'
'app': mydashboardapp,
# priority of the dashboard in the left menu (lower is higher in the
# menu)
'order': 5,
# An available icon list can be found at http://fontawesome.io/icons/. Double-check
# the buildbot about dashboard for the installed version of Font Awesome as the
# published icons may include more recently additions.
'icon': 'area-chart'
}
]
15 changes: 15 additions & 0 deletions smokes-react/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "smokes-react",
"version": "1.0.0",
"description": "smoke tests for buildbot with cypress",
"main": "index.js",
"dependencies": {
"@playwright/test": "^1.37.0",
"qs": "^6.11",
"request": "^2.88.2",
"typescript": "^4.4.2"
},
"scripts": {},
"author": "",
"license": "GPL2.0"
}
63 changes: 63 additions & 0 deletions smokes-react/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
testDir: './tests',
/* Run tests in files in parallel */
fullyParallel: false,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests */
workers: 1,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'line',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: 'http://localhost:8011',

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',

testIdAttribute: 'data-bb-test-id'
},

/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},

{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},

{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},

/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: { ...devices['Pixel 5'] },
// },
// {
// name: 'Mobile Safari',
// use: { ...devices['iPhone 12'] },
// },

/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
// },
// {
// name: 'Google Chrome',
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
// },
],
});
Loading
Loading