From 04b04219a3356c523200c4b69e30d6857138915c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 26 Jan 2026 13:18:29 +0000 Subject: [PATCH 1/6] Initial plan From 047ac99dcf442745762b6bafbeb0eb9a3c58e410 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 26 Jan 2026 13:21:29 +0000 Subject: [PATCH 2/6] Add test files from playwright-tests branch Co-authored-by: gtheler <9962631+gtheler@users.noreply.github.com> --- .github/workflows/playwright.yml | 103 ++++++++++++++++ .gitignore | 3 + autoclean.sh | 8 +- cadimporters/upload/gmshcheck.py | 7 -- cadprocessors/gmsh/cadimport.py | 1 + cadprocessors/gmsh/gmshcheck.py | 22 ++++ cadprocessors/gmsh/process.php | 12 +- deps.sh | 8 +- html/check.php | 200 +++++++++++++++++++++++++++++++ html/common.php | 37 ++++-- meshers/gmsh/deps.sh | 2 + package-lock.json | 75 ++++++++++++ package.json | 26 ++++ playwright.config.js | 28 +++++ renderers/x3dom/deps.sh | 4 +- solvers/feenox/deps.sh | 8 +- tests/e2e/create_case.spec.js | 38 ++++++ tests/e2e/example.spec.js | 9 ++ uxs/faster-than-quick/about.php | 7 +- uxs/faster-than-quick/deps.sh | 3 +- 20 files changed, 564 insertions(+), 37 deletions(-) create mode 100644 .github/workflows/playwright.yml delete mode 100755 cadimporters/upload/gmshcheck.py create mode 100755 cadprocessors/gmsh/gmshcheck.py create mode 100644 html/check.php create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 playwright.config.js create mode 100644 tests/e2e/create_case.spec.js create mode 100644 tests/e2e/example.spec.js diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml new file mode 100644 index 0000000..18ff1c2 --- /dev/null +++ b/.github/workflows/playwright.yml @@ -0,0 +1,103 @@ +name: Playwright Tests + +on: + push: + branches: [ main, master ] + pull_request: + branches: [ main, master ] + +jobs: + playwrigth-standalone: + timeout-minutes: 60 + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.3' + extensions: yaml + + - name: Install System Dependencies + run: | + sudo apt-get update + sudo apt-get install -y unzip patchelf wget php-cli php-yaml gnuplot + + - name: Install SunCAE Dependencies (FeenoX & Gmsh) standalone + run: ./deps.sh + + - name: Check script + run: php html/check.php + + - name: Install Node Dependencies + run: npm ci + + - name: Install Playwright Browsers + run: npx playwright install --with-deps + + - name: Run Playwright tests + run: npx playwright test + + - name: Upload Playwright Report + if: failure() + uses: actions/upload-artifact@v4 + with: + name: playwright-report-standalone + path: playwright-report-stanadlone/ + retention-days: 30 + + playwrigth-apt: + timeout-minutes: 60 + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.3' + extensions: yaml + + - name: Install System Dependencies + run: | + sudo apt-get update + sudo apt-get install -y unzip patchelf wget php-cli php-yaml gnuplot + +# feenox 1.2 is not available in ubuntu 24.04, only in 25.10 + - name: Install SunCAE Dependencies (FeenoX & Gmsh) from apt + run: | + sudo apt-get install -y python3-gmsh pandoc + ./deps.sh + + - name: Check script + run: php html/check.php + + - name: Install Node Dependencies + run: npm ci + + - name: Install Playwright Browsers + run: npx playwright install --with-deps + + - name: Run Playwright tests + run: npx playwright test + + - name: Upload Playwright Report + if: failure() + uses: actions/upload-artifact@v4 + with: + name: playwright-report-apt + path: playwright-report-apt/ + retention-days: 30 diff --git a/.gitignore b/.gitignore index ea89aa9..d1b551e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ bin deps data +node_modules/ +test-results/ +playwright-report/ diff --git a/autoclean.sh b/autoclean.sh index a7e1240..f89bf50 100644 --- a/autoclean.sh +++ b/autoclean.sh @@ -16,7 +16,8 @@ if [ ! -d auths ]; then echo 1 fi -for i in bin deps data; do +# cat .gitgnore? +for i in bin deps data node_modules test-results playwright-report; do echo -n "cleaning ${i}... " rm -rf ${i} || exit 1 echo "ok" @@ -32,3 +33,8 @@ for i in $(find . -name .gitignore); do cd ${pwd} fi done + +# more +for i in x3dom.js x3dom.css; do + find . -name {$i} | xargs rm -f +done diff --git a/cadimporters/upload/gmshcheck.py b/cadimporters/upload/gmshcheck.py deleted file mode 100755 index 0722292..0000000 --- a/cadimporters/upload/gmshcheck.py +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/python3 -import sys -sys.path.append("../../../../bin") -import gmsh - -gmsh.initialize() -gmsh.finalize() diff --git a/cadprocessors/gmsh/cadimport.py b/cadprocessors/gmsh/cadimport.py index 1779891..efc7f7f 100755 --- a/cadprocessors/gmsh/cadimport.py +++ b/cadprocessors/gmsh/cadimport.py @@ -1,5 +1,6 @@ #!/usr/bin/python3 import sys +sys.path.append("../../bin") sys.path.append("../../../../bin") import gmsh import os diff --git a/cadprocessors/gmsh/gmshcheck.py b/cadprocessors/gmsh/gmshcheck.py new file mode 100755 index 0000000..109d850 --- /dev/null +++ b/cadprocessors/gmsh/gmshcheck.py @@ -0,0 +1,22 @@ +#!/usr/bin/python3 +import sys +import os + +script_dir = os.path.dirname(os.path.abspath(__file__)) +bin_dir = os.path.join(script_dir, '../../', 'bin') # if bin is one level up +if os.path.exists(bin_dir): + sys.path.insert(0, bin_dir) + +import gmsh + +# Initialize the Gmsh API +gmsh.initialize() + +# Get the Gmsh version string +version = gmsh.option.getString("General.Version") + +# Print the version +print(version) + +# Finalize the Gmsh API +gmsh.finalize() diff --git a/cadprocessors/gmsh/process.php b/cadprocessors/gmsh/process.php index 00154c3..a2cae73 100644 --- a/cadprocessors/gmsh/process.php +++ b/cadprocessors/gmsh/process.php @@ -14,16 +14,20 @@ return_error_json("username is empty"); } -$cad_dir = "../../data/{$username}/cads/{$cad_hash}"; +$cad_dir = $data_dir . "{$username}/cads/{$cad_hash}"; if (file_exists($cad_dir) === false) { - mkdir($cad_dir, $permissions, true); + if (mkdir($cad_dir, $permissions, true) === false) { + return_error_json("cannot mkdir {$cad_dir}"); + } +} +if (chdir($cad_dir) === false) { + return_error_json("cannot chdir to {$cad_dir}"); } -chdir($cad_dir); // ------------------------------------------------------------ if (file_exists("cad.json") === false) { exec(sprintf("%s/cadimport.py 2>&1", __DIR__), $output, $error_level); - + // TODO: keep output if ($error_level != 0) { $error_message = "Error {$error_level} when importing CAD: "; diff --git a/deps.sh b/deps.sh index 7985bc0..1db9b64 100755 --- a/deps.sh +++ b/deps.sh @@ -19,15 +19,19 @@ for i in wget tar unzip python3; do fi done +# create gitignored directories +mkdir -p deps bin + +# this one needs to be either world writable or owned by the user running the web server +# we start with 0777 but a sane admin would change it back to 0744 (or less) if [ ! -d data ]; then mkdir -p data chmod 0777 data fi -mkdir -p deps -# Function to compare versions (include in main deps.sh or source from a utils file) +# Function to compare versions version_ge() { printf '%s\n%s\n' "$2" "$1" | sort -V -C return $? diff --git a/html/check.php b/html/check.php new file mode 100644 index 0000000..bc1454b --- /dev/null +++ b/html/check.php @@ -0,0 +1,200 @@ +\n"; + +$username_output = []; +exec('whoami', $username_output); +$user = $username_output[0]; + +echo "[info] username running the web server is {$user}
\n"; + +if (file_exists($data_dir) === false) { + if (mkdir($data_dir, 0777) === false) { + echo "[error] cannot create data dir {$data_dir}
\n"; + exit(1); + } +} else { + if (is_dir($data_dir) === false) { + echo "[error] data dir exists but is not a directory
\n"; + exit(2); + } +} + +if (is_writable($data_dir)) { + echo "[good] {$data_dir} is writable by user {$user}
\n"; +} else { + echo "[error] {$data_dir} is not writable by user {$user}
\n"; + exit(3); +} + +// --- bin dir ---------------- +$bin_dir = __DIR__ . "/../bin"; +echo "[info] bin_dir is {$bin_dir}
\n"; + +if (file_exists($bin_dir) && is_dir($bin_dir)) { + echo "[good] {$bin_dir} exists
\n"; +} else { + echo "[error] {$bin_dir} does not exist
\n"; + exit(4); +} + + + + +// --- logging ---------------------------------- +include(__DIR__ . "/common.php"); +$username = "root"; +$err = suncae_log("running check.php script"); + +if ($err == 0) { + echo "[good] logging works
\n"; +} else { + echo "[error] cannot create a log entry
\n"; + exit(5); +} + + +// conf +include(__DIR__ . "/../conf.php"); + +// --- auth ---------------------------------- +if (file_exists(__DIR__ . "/../auths/{$auth}/auth.php")) { + echo "[good] auth {$auth} exists
\n"; +} else { + echo "[error] auth {$auth} does not exist
\n"; + exit(6); +} + +// --- ux ---------------------------------- +if (file_exists(__DIR__ . "/../uxs/{$ux}/index.php")) { + echo "[good] ux {$ux} exists
\n"; +} else { + echo "[error] ux {$ux} does not exist
\n"; + exit(7); +} + +if ($ux == "faster-than-quick") { + foreach (['css/bootstrap.min.css', 'css/katex.min.css', 'css/x3dom.css'] as $i) { + if (file_exists(__DIR__ . "/../uxs/{$ux}/{$i}")) { + echo "[good] {$i} exists
\n"; + } else { + echo "[error] {$i} does not exist
\n"; + exit(8); + } + } + + // pandoc + if (file_exists("{$bin_dir}/pandoc")) { + echo "[good] pandoc binary exists
\n"; + echo "[info] " . shell_exec("ls -la {$bin_dir}/pandoc") . "
\n"; + } else { + echo "[error] pandoc binary does not exist
\n"; + exit(9); + } + $exec_output = []; + exec("{$bin_dir}/pandoc --version 2>&1", $exec_output, $err); + // TODO: check version is good enough + if ($err == 0) { + echo "[good] pandoc version is {$exec_output[0]}
\n"; + } else { + echo "[error] pandoc binary does not work
\n"; + for ($i = 0; $i < count($exec_output); $i++) { + echo "[info] {$exec_output[$i]}
\n"; + } + exit(10); + } +} + + +// --- cadimporter ---------------------------------- +if (file_exists(__DIR__ . "/../cadimporters/{$cadimporter}/import_cad.php")) { + echo "[good] cadimporter {$cadimporter} exists
\n"; +} else { + echo "[error] cadimporters {$cadimporter} does not exist
\n"; + exit(11); +} + + + +// --- cadprocessor ---------------------------------- +if (file_exists(__DIR__ . "/../cadprocessors/{$cadprocessor}/process.php")) { + echo "[good] cadprocessor {$cadprocessor} exists
\n"; +} else { + echo "[error] cadprocessor {$cadprocessor} does not exist
\n"; + exit(12); +} + + +if ($cadprocessor == "gmsh") { + foreach (['css/bootstrap.min.css', 'css/katex.min.css', 'css/x3dom.css'] as $i) { + if (file_exists(__DIR__ . "/../uxs/{$ux}/{$i}")) { + echo "[good] {$i} exists
\n"; + } else { + echo "[error] {$i} does not exist
\n"; + exit(13); + } + } + + // gmsh + if (file_exists("{$bin_dir}/gmsh")) { + echo "[good] gmsh binary exists
\n"; + echo "[info] " . shell_exec("ls -la {$bin_dir}/gmsh") . "
\n"; + } else { + echo "[error] gmsh binary does not exist
\n"; + exit(14); + } + $exec_output = []; + exec("{$bin_dir}/gmsh -version 2>&1", $exec_output, $err); + // TODO: check version is good enough + if ($err == 0) { + echo "[good] gmsh version is {$exec_output[0]}
\n"; + } else { + echo "[error] gmsh binary does not work
\n"; + for ($i = 0; $i < count($exec_output); $i++) { + echo "[info] {$exec_output[$i]}
\n"; + } + exit(15); + } + + // python + $exec_output = []; + exec("which python", $exec_output, $err); + if ($err == 0) { + echo "[good] python binary exists at {$exec_output[0]}
\n"; + } else { + echo "[error] python binary does not exist
\n"; + exit(16); + } + $exec_output = []; + exec("python --version 2>&1", $exec_output, $err); + // TODO: check version is good enough + if ($err == 0) { + echo "[good] python version is {$exec_output[0]}
\n"; + } else { + echo "[error] python binary does not work
\n"; + for ($i = 0; $i < count($exec_output); $i++) { + echo "[info] {$exec_output[$i]}
\n"; + } + exit(17); + } + + // gmsh python wrapper + $exec_output = []; + exec("python " . __DIR__ . "/../cadprocessors/gmsh/gmshcheck.py 2>&1", $exec_output, $err); + // TODO: check version is good enough + if ($err == 0) { + echo "[good] python gmsh wrapper version is {$exec_output[0]}
\n"; + } else { + echo "[error] python gmsh wrapper does not work
\n"; + for ($i = 0; $i < count($exec_output); $i++) { + echo "[info] {$exec_output[$i]}
\n"; + } + exit(18); + } + + // TODO: check python and binary versions match + + +} diff --git a/html/common.php b/html/common.php index a1e52fe..ec90dfe 100644 --- a/html/common.php +++ b/html/common.php @@ -3,8 +3,15 @@ // SunCAE is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. // SunCAE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. -$permissions = 0755; +$permissions = 0777; $id = (isset($_POST["id"])) ? $_POST["id"] : ((isset($_GET["id"])) ? $_GET["id"] : ""); +$data_dir = __DIR__ . "/../data/"; +if (file_exists($data_dir) === false) { + if (mkdir($data_dir, $permissions, true) === false) { + echo "cannot mkdir {$data_dir}, please check permissions"; + exit(1); + } +} // based on original work from the PHP Laravel framework if (!function_exists('str_contains')) { @@ -16,12 +23,14 @@ function str_contains($haystack, $needle) { function suncae_log_write($file_path, $username, $message) { $log = fopen($file_path, "a"); - if ($log === false) { - suncae_error("Cannot open log file, please check permissions."); + if ($log) { + $ip = (isset($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : "localhost"; + fprintf($log, "%s %s\t%s: %s\n", date("c"), $ip, $username, $message); + fclose($log); + return 0; + } else { + return 1; } - fprintf($log, "%s %s\t%s: %s\n", date("c"), $_SERVER['REMOTE_ADDR'], $username, $message); - fclose($log); - } function suncae_log_error($message, $level = 0) { @@ -33,7 +42,7 @@ function suncae_log_error($message, $level = 0) { $log_dir = __DIR__ . "/../data/logs/"; if (file_exists($log_dir) == false) { if (mkdir($log_dir, $permissions, true) == false) { - suncae_error("error: cannot create log directory"); + exit(1); } } @@ -43,7 +52,6 @@ function suncae_log_error($message, $level = 0) { if ($level > 0) { suncae_log_write("{$log_dir}0-{$date}.log", $username, $message); } - } @@ -64,25 +72,30 @@ function suncae_log($message, $level = 0) { $log_dir = __DIR__ . "/../data/logs/"; if (file_exists($log_dir) == false) { if (mkdir($log_dir, $permissions, true) == false) { - suncae_error("error: cannot create log directory"); + return 1; } } $date = date('Y-m-d'); suncae_log_write("{$log_dir}0-{$date}.log", $username, $message); if ($level > 0) { - suncae_log_write("{$log_dir}{$level}-{$date}.log", $username, $message); + if (suncae_log_write("{$log_dir}{$level}-{$date}.log", $username, $message) != 0) { + return 1; + } } if ($username != "anonymous") { $log_dir = __DIR__ . "/../data/{$username}/"; if (file_exists($log_dir) == false) { if (mkdir($log_dir, $permissions, true) == false) { - suncae_error("error: cannot create log directory"); + return 2; } } - suncae_log_write("{$log_dir}activity.log", $username, $message); + if (suncae_log_write("{$log_dir}activity.log", $username, $message) != 0) { + return 1; + } } + return 0; } diff --git a/meshers/gmsh/deps.sh b/meshers/gmsh/deps.sh index af53a80..538ac5b 100644 --- a/meshers/gmsh/deps.sh +++ b/meshers/gmsh/deps.sh @@ -36,11 +36,13 @@ if [ $use_system_binary = 0 ]; then echo "error: downloaded gmsh needs ${i}, please do sudo apt install patchelf" exit 1 fi + mkdir -p bin cd deps if [ ! -e ${gmsh_tarball}.tgz ]; then wget -c http://gmsh.info/bin/Linux/${gmsh_tarball}.tgz fi tar xzf ${gmsh_tarball}.tgz + rm -f ../bin/gmsh.py ../bin/gmsh ../bin/libgmsh.so* cp ${gmsh_tarball}/bin/gmsh ../bin cp ${gmsh_tarball}/lib/gmsh.py ../bin cp -d ${gmsh_tarball}/lib/libgmsh.so* ../bin diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..ba8c545 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,75 @@ +{ + "name": "suncae", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "suncae", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "@playwright/test": "^1.57.0" + } + }, + "node_modules/@playwright/test": { + "version": "1.57.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.57.0.tgz", + "integrity": "sha512-6TyEnHgd6SArQO8UO2OMTxshln3QMWBtPGrOCgs3wVEmQmwyuNtB10IZMfmYDE0riwNR1cu4q+pPcxMVtaG3TA==", + "dev": true, + "dependencies": { + "playwright": "1.57.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/playwright": { + "version": "1.57.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.57.0.tgz", + "integrity": "sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw==", + "dev": true, + "dependencies": { + "playwright-core": "1.57.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.57.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.57.0.tgz", + "integrity": "sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..f9672cc --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "suncae", + "version": "1.0.0", + "description": "![](doc/logo.svg)", + "main": "index.js", + "directories": { + "doc": "doc" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/seamplex/suncae.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/seamplex/suncae/issues" + }, + "homepage": "https://github.com/seamplex/suncae#readme", + "devDependencies": { + "@playwright/test": "^1.57.0" + } +} diff --git a/playwright.config.js b/playwright.config.js new file mode 100644 index 0000000..3e3f7ea --- /dev/null +++ b/playwright.config.js @@ -0,0 +1,28 @@ +// @ts-check +const { defineConfig, devices } = require('@playwright/test'); + +module.exports = defineConfig({ + testDir: './tests/e2e', + fullyParallel: true, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 2 : 0, + workers: process.env.CI ? 1 : undefined, + reporter: 'html', + use: { + baseURL: 'http://localhost:8000', + trace: 'on-first-retry', + }, + + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + ], + + webServer: { + command: 'php -S localhost:8000 -t html', + url: 'http://localhost:8000', + reuseExistingServer: !process.env.CI, + }, +}); diff --git a/renderers/x3dom/deps.sh b/renderers/x3dom/deps.sh index 826ec60..93b629a 100644 --- a/renderers/x3dom/deps.sh +++ b/renderers/x3dom/deps.sh @@ -19,8 +19,8 @@ if [ $force = 1 ] || [ ! -e renderers/x3dom/x3dom.js ]; then # cp x3dom/x3dom.js ../renderers/x3dom # cp x3dom/x3dom.css ../renderers/x3dom - wget -c https://andreasplesch.github.io/x3dom/dist/x3dom.js -o ../renderers/x3dom/x3dom.js - wget -c https://andreasplesch.github.io/x3dom/dist/x3dom.css -o ../renderers/x3dom/x3dom.css + wget -c https://andreasplesch.github.io/x3dom/dist/x3dom.js -O ../renderers/x3dom/x3dom.js + wget -c https://andreasplesch.github.io/x3dom/dist/x3dom.css -O ../renderers/x3dom/x3dom.css cd ../uxs/faster-than-quick/js if [ ! -e x3dom.js ]; then diff --git a/solvers/feenox/deps.sh b/solvers/feenox/deps.sh index f235db6..9fb4e31 100644 --- a/solvers/feenox/deps.sh +++ b/solvers/feenox/deps.sh @@ -1,6 +1,6 @@ #!/bin/false -feenox_version=1.2 +feenox_version=1.2.1 feenox_version_min=1.72 # feenox @@ -16,14 +16,14 @@ echo -n "meshers/feenox... " use_system_binary=0 if [ -x "$(which feenox 2>/dev/null)" ] && [ $force = 0 ]; then installed_version=$(get_feenox_version "$(which feenox)") - if [ -n "$installed_version" ] && version_ge "$installed_version" "$feenox_min_version"; then - echo "found system version $installed_version (>= $feenox_min_version), using it" + if [ -n "$installed_version" ] && version_ge "$installed_version" "$feenox_version_min"; then + echo "found system version $installed_version (>= $feenox_version_min), using it" use_system_binary=1 # Create symlink to system binary mkdir -p bin ln -sf "$(which feenox)" bin/feenox else - echo "system version $installed_version is too old (need >= $feenox_min_version), will download" + echo "system version $installed_version is too old (need >= $feenox_version_min), will download" fi fi diff --git a/tests/e2e/create_case.spec.js b/tests/e2e/create_case.spec.js new file mode 100644 index 0000000..55ddb35 --- /dev/null +++ b/tests/e2e/create_case.spec.js @@ -0,0 +1,38 @@ +// @ts-check +const { test, expect } = require('@playwright/test'); +const path = require('path'); + +test('create new case from sample.step', async ({ page }) => { + // 1. Go to /new + await page.goto('/new/'); + + // 2. In that view, there's a file upload input box. Put the file html/new/sample.step in the upload box + // Note: path is relative to the test file. + // tests/e2e/create_case.spec.js -> ../../html/new/sample.step + const sampleFile = path.join(__dirname, '../../html/new/sample.step'); + await page.setInputFiles('#cad', sampleFile); + + // Wait for the file to be processed and preview to be shown + await expect(page.locator('#cad_preview')).toBeVisible({ timeout: 30000 }); + + // 3. Select "Solid mechanics" in the combo box for physics + await page.selectOption('#physics', 'solid'); + + // 4. Select "Mechanical elasticty" in the combo box for problem + await page.selectOption('#problem', 'mechanical'); + + // 5. Select "FeenoX" in the combo box for solver + await page.selectOption('#solver', 'feenox'); + + // 6. Select "Gmsh" in thecombo box for mesher + await page.selectOption('#mesher', 'gmsh'); + + // Verify start button is enabled before clicking + await expect(page.locator('#btn_start')).toBeEnabled(); + + // 7. Click "Start" + await page.click('#btn_start'); + + // Optional: Verify we moved to the next step (e.g., URL changes to create.php or creating a case) + // For now, just ensuring no error occurs immediately after click. +}); diff --git a/tests/e2e/example.spec.js b/tests/e2e/example.spec.js new file mode 100644 index 0000000..f36a88d --- /dev/null +++ b/tests/e2e/example.spec.js @@ -0,0 +1,9 @@ +// @ts-check +const { test, expect } = require('@playwright/test'); + +test('homepage has title', async ({ page }) => { + await page.goto('/'); + + // Expect a title "to contain" a substring. + await expect(page).toHaveTitle(/Faster-than-quick/); +}); diff --git a/uxs/faster-than-quick/about.php b/uxs/faster-than-quick/about.php index 7f3134d..be6f335 100644 --- a/uxs/faster-than-quick/about.php +++ b/uxs/faster-than-quick/about.php @@ -18,16 +18,15 @@
Versions
"; -echo "Gmsh ".`../bin/gmsh -info | head -n1`; +// get versions from a txt file? ?> +To be done.
License
GNU Affero General Public License version 3, or at your option, any later version. You can get a copy of the source code of this web interface here. - +