Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions .github/workflows/testing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: "Run end-to-end tests for PaperWM"

on:
push:
paths:
- '*.nix'
- '*.js'
- 'tests/**'

jobs:
run-tests:
name: Run unit tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Nix
uses: cachix/install-nix-action@v20
- name: Enable KVM group perms
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
sudo tee -a /etc/nix/nix.conf <<< "extra-system-features = kvm nixos-test"
- name: Build test VM
run: |
nix build .#vm
- name: Launch tests
run: |
for file in tests/features/*.feature
do
echo "::group::Test ${file##*/}"
feat="${file##*/}"
nix run .#checks.x86_64-linux.${feat%%.feature}.driver
echo "::endgroup::"
done
- name: Save results
uses: actions/upload-artifact@v7
if: always()
with:
name: allure-output
path: allure_output

push-reports:
name: Upload HTML reports to Pages
needs: run-tests
if: always()
runs-on: ubuntu-latest
permissions:
statuses: write
contents: write
pages: write
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Fetch report
uses: actions/download-artifact@v8
with:
name: allure-output
path: allure_output
- name: Deploy report to GitHub Pages
id: report
uses: PavanMudigonda/html-reporter-github-pages@v1.5.21
with:
test_results: allure_output
allure_report_generate_flag: true
keep_reports: 10
gh_pages: pages_reports
workflow_name: ${{ github.workflow }}
use_actions_summary: true
- name: Notify about generated report
uses: guibranco/github-status-action-v2@v1.1.14
with:
authToken: ${{ secrets.GITHUB_TOKEN }}
context: PaperWM test reports
description: Click here to open test reports
state: success
sha: ${{github.event.pull_request.head.sha || github.sha}}
target_url: ${{env.GITHUB_PAGES_WEBSITE_URL}}/${{github.run_number}}/index.html
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ package-lock.json

# generated disk image for test VM
nixos.qcow2

# generated test outputs
allure_output/
scr-*.png
2 changes: 2 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import * as Main from 'resource:///org/gnome/shell/ui/main.js';

import { Patches, Tiling } from './imports.js';

export const name = "app";

/*
Application functionality, like global new window actions etc.
*/
Expand Down
2 changes: 1 addition & 1 deletion default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ stdenv.mkDerivation {

makeFlags = [ "SOURCE=$(src)" "EXT_DIR=$(out)/share/gnome-shell/extensions" ];

nativeBuildInputs = with pkgs;
nativeBuildInputs =
[ glib
];

Expand Down
5 changes: 5 additions & 0 deletions extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ export default class PaperWM extends Extension {
Workspace, Tiling, Topbar, App, Grab,
];

// Name-based introspection for unit tests
findModule(name) {
return this.modules.find((m) => m.name == name);
}

#userStylesheet = null;

enable() {
Expand Down
23 changes: 20 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

90 changes: 61 additions & 29 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -1,9 +1,43 @@
{ description = "Tiled, scrollable window management for GNOME Shell";

inputs."nixpkgs".url = github:NixOS/nixpkgs;
inputs."nixpkgs-gnome".url = github:vitorpavani/nixpkgs/gnome-50-bump;
inputs =
{ "nixpkgs".url = "github:NixOS/nixpkgs";
"nixpkgs-gnome".url = "github:vitorpavani/nixpkgs/gnome-50-bump";

outputs = { self, nixpkgs, nixpkgs-gnome, flake-utils, ... }:
"gtk-stream".url = "git+https://git.sr.ht/~marc-coiffier/gtk-stream";
"gtk-stream".flake = false;
};

outputs = { self, nixpkgs, nixpkgs-gnome, flake-utils, gtk-stream, ... }:
let
testSystem = "x86_64-linux";
pkgs-gnome = import nixpkgs-gnome { system = testSystem; };
gnomeOverlay = (s: super: {
gnome-desktop = pkgs-gnome.gnome-desktop;
gnome-shell = pkgs-gnome.gnome-shell.override {
evolution-data-server-gtk4 = super.evolution-data-server-gtk4.override {
inherit (super) webkitgtk_4_1 webkitgtk_6_0;
};
};
gnome-session = pkgs-gnome.gnome-session.override {
inherit (s) gnome-shell;
};
gnome-control-center = pkgs-gnome.gnome-control-center;
gnome-initial-setup = pkgs-gnome.gnome-initial-setup.override {
inherit (super) webkitgtk_6_0;
};
gnome-settings-daemon = pkgs-gnome.gnome-settings-daemon;
mutter = pkgs-gnome.mutter;
gdm = pkgs-gnome.gdm;
xdg-desktop-portal-gnome = pkgs-gnome.xdg-desktop-portal-gnome;
xdg-desktop-portal-gtk = pkgs-gnome.xdg-desktop-portal-gtk;
});

# NixOS usually takes its sweet time updating to latest GNOME.
# Enable this to use the GNOME version from their dedicated dev branch.
#WARN: build times may increase significantly!
useGnomeStaging = true;
in
flake-utils.lib.eachDefaultSystem
(system:
let hostPkgs = import nixpkgs { inherit system; };
Expand All @@ -21,40 +55,38 @@
})
];
};
in localConfig.config.system.build.vm;
in localConfig.config.system.build.vm;

checks = import ./tests {
system = testSystem;
pkgs = import nixpkgs { system = testSystem; };
defaultConfig = { pkgs, ... }: {
imports = [ ./vm.nix ];
nixpkgs.overlays = [
(s: super: {
paperwm = self.packages.${testSystem}.default;
gtk-stream = s.callPackage gtk-stream {};
})

(if useGnomeStaging then gnomeOverlay else (s: super: {}))
];
};
};
}) // {
nixosConfigurations."testbox" =
let system = "x86_64-linux";
pkgs-gnome = import nixpkgs-gnome { inherit system; };
in nixpkgs.lib.nixosSystem {
inherit system;
nixpkgs.lib.nixosSystem {
system = testSystem;
modules = [
./vm.nix
{ nixpkgs.overlays = [
# Introduce PaperWM into our extensions
(s: super: { paperwm = self.packages.${system}.default; })

# Pull GNOME-specific packages from GNOME staging
(s: super: {
gnome-desktop = pkgs-gnome.gnome-desktop;
gnome-shell = pkgs-gnome.gnome-shell.override {
evolution-data-server-gtk4 = super.evolution-data-server-gtk4.override {
inherit (super) webkitgtk_4_1 webkitgtk_6_0;
};
};
gnome-session = pkgs-gnome.gnome-session.override {
inherit (s) gnome-shell;
};
gnome-control-center = pkgs-gnome.gnome-control-center;
gnome-initial-setup = pkgs-gnome.gnome-initial-setup.override {
inherit (super) webkitgtk_6_0;
};
gnome-settings-daemon = pkgs-gnome.gnome-settings-daemon;
mutter = pkgs-gnome.mutter;
gdm = pkgs-gnome.gdm;
xdg-desktop-portal-gnome = pkgs-gnome.xdg-desktop-portal-gnome;
xdg-desktop-portal-gtk = pkgs-gnome.xdg-desktop-portal-gtk;
paperwm = self.packages.${testSystem}.default;
gtk-stream = s.callPackage gtk-stream {};
})

# Pull GNOME-specific packages from GNOME staging
(if useGnomeStaging then gnomeOverlay else (s: super: {}))
];
}
];
Expand Down
2 changes: 2 additions & 0 deletions gestures.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import { Patches, Settings, Tiling, Utils, Lib, Navigator } from './imports.js';
import { Easer } from './utils.js';

export const name = "gestures";

const DIRECTIONS = {
Horizontal: true,
Vertical: false,
Expand Down
2 changes: 2 additions & 0 deletions grab.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import { Settings, Utils, Tiling, Navigator, Scratch, Gestures } from './imports.js';
import { DispatcherMode, Easer } from './utils.js';

export const name = "grab";

export let grabbed = false;

/**
Expand Down
2 changes: 2 additions & 0 deletions keybindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
App, Scratch, LiveAltTab, Topbar
} from './imports.js';

export const name = "keybindings";

const Seat = Clutter.get_default_backend().get_default_seat();
const display = global.display;

Expand Down
2 changes: 2 additions & 0 deletions liveAltTab.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import * as AltTab from 'resource:///org/gnome/shell/ui/altTab.js';
import { Settings, Keybindings, Tiling, Scratch, Utils } from './imports.js';
import { Easer } from './utils.js';

export const name = "liveAltTab";

let switcherSettings;
export function enable() {
switcherSettings = new Gio.Settings({
Expand Down
2 changes: 2 additions & 0 deletions navigator.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
Scratch, Minimap, Settings
} from './imports.js';

export const name = "navigator";

/**
Navigation and previewing functionality.

Expand Down
2 changes: 2 additions & 0 deletions patches.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import * as Screenshot from 'resource:///org/gnome/shell/ui/screenshot.js';

import { Utils, Tiling, Scratch, Settings, OverviewLayout } from './imports.js';

export const name = "patches";

/**
Some of Gnome Shell's default behavior is really sub-optimal when using
paperWM. Other features are simply not possible to implement without monkey
Expand Down
2 changes: 2 additions & 0 deletions scratch.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import * as WindowMenu from 'resource:///org/gnome/shell/ui/windowMenu.js';
import { Settings, Utils, Tiling, Topbar } from './imports.js';
import { Easer } from './utils.js';

export const name = "scratch";

let originalBuildMenu;
let float, scratchFrame; // symbols used for expando properties on metawindow
export function enable() {
Expand Down
2 changes: 2 additions & 0 deletions settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { AcceleratorParse } from './acceleratorparse.js';
at the top).
*/

export const name = "settings";

const KEYBINDINGS_KEY = 'org.gnome.shell.extensions.paperwm.keybindings';
const RESTORE_KEYBINDS_KEY = 'restore-keybinds';

Expand Down
2 changes: 2 additions & 0 deletions stackoverlay.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import * as PointerWatcher from 'resource:///org/gnome/shell/ui/pointerWatcher.j

import { Settings, Utils, Tiling, Grab, Scratch } from './imports.js';

export const name = "stackoverlay";

/*
The stack overlay decorates the top stacked window with its icon and
captures mouse input such that a mouse click only _activates_ the
Expand Down
23 changes: 23 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# PaperWM end-to-end tests

Unit tests on PaperWM are carried out using the [test VM](https://github.com/PaperWM/PaperWM/wiki/Using-the-test-VM), a NixOS virtual machine connected to a Python testing harness, and [Behave](https://behave.readthedocs.io), an implementation of the Gherkin unit testing language.

## Layout

### `default.nix` and `template.nix`

These files are NixOS boilerplate code that scan for features in the `features` directory and generate test VMs accordingly. You can use them to register tests that require extra dependencies not found in the base test VM, such as specific misbehaving applications.

### `features`

This is the directory where Behave feature tests and their Python implementations are found. Each `.feature` file maps to a NixOS unit test, which can be overridden in `default.nix` as mentioned above.

The usual testing loop is to record user input from within the VM, and replay them in the order specified in the feature file.

### `recordings`

This directory contains recordings of all input devices in the VM (touchpad, touchscreen, keyboard...), meant to be replayed as-is in the VM by the feature tests. Please only add recordings made from within the test VM.

### `screenshots`

This directory contains predicate screenshots to check against, to determine whether a test was successful.
Loading
Loading