Developer-Dashboard
view release on metacpan or search on metacpan
t/31-sql-dashboard-sqlite-playwright.t view on Meta::CPAN
},
label => 'Playwright sqlite sql-dashboard matrix',
);
is( $playwright_result->{stderr}, '', 'sqlite sql-dashboard Playwright matrix keeps stderr clean' );
my $payload = $playwright_result->{stdout} ne ''
? _json_decode( $playwright_result->{stdout} )
: {
ok => 0,
cases => [],
consoleMessages => [],
pageErrors => [],
};
ok( $payload->{ok}, 'sqlite sql-dashboard Playwright matrix reports success' )
or diag _diagnostic_text($payload);
is( scalar @{ $payload->{cases} || [] }, 54, 'sqlite sql-dashboard Playwright matrix records 54 UX and limit cases' );
for my $case ( @{ $payload->{cases} || [] } ) {
ok( $case->{ok}, $case->{name} ) or diag _case_diagnostic($case);
}
my $saved_profile = File::Spec->catfile( $sql_config_root, 'SQLite Local.json' );
my $saved_collection = File::Spec->catfile( $collection_root, 'SQLite Reporting.json' );
ok( !-e $saved_profile, 'shared-url SQLite draft restoration deletes the saved sqlite profile before the final reload check' );
ok( -f $saved_collection, 'sqlite Playwright matrix keeps the saved SQL collection on disk' );
like( _read_text($saved_collection), qr/"name"\s*:\s*"SQLite Reporting"/, 'sqlite Playwright matrix persists the browser-created SQLite collection name' );
is( _mode_octal($sql_config_root), '0700', 'sqlite Playwright matrix keeps the sql-dashboard config root owner-only' );
is( _mode_octal($collection_root), '0700', 'sqlite Playwright matrix keeps the sql-dashboard collection root owner-only' );
is( _mode_octal($saved_collection), '0600', 'sqlite Playwright matrix keeps the saved SQLite collection file owner-only' );
1;
} or do {
my $error = $@ || 'SQLite sql-dashboard Playwright matrix failed';
diag $error;
diag _read_text($dashboard_log) if -f $dashboard_log;
_stop_dashboard_server(
cwd => $project_root,
home => $home_root,
repo_lib => $repo_lib,
dashboard_bin => $dashboard_bin,
pid => $dashboard_pid,
) if $dashboard_pid;
die $error;
};
_stop_dashboard_server(
cwd => $project_root,
home => $home_root,
repo_lib => $repo_lib,
dashboard_bin => $dashboard_bin,
pid => $dashboard_pid,
) if $dashboard_pid;
done_testing;
# _playwright_script()
# Purpose: build the Chromium Playwright regression script for the real SQLite browser matrix.
# Input: no arguments.
# Output: JavaScript source string that writes JSON case results to stdout.
sub _playwright_script {
return <<'JS';
const path = require('path');
const { chromium } = require(path.join(process.env.PLAYWRIGHT_DIR, 'index.js'));
async function main() {
const browser = await chromium.launch({
executablePath: process.env.CHROMIUM_BIN,
headless: true
});
const page = await browser.newPage();
const consoleMessages = [];
const pageErrors = [];
const cases = [];
function record(name, ok, detail) {
cases.push({ name, ok: !!ok, detail: detail || '' });
}
async function check(name, fn) {
try {
await fn();
record(name, true, '');
} catch (error) {
record(name, false, String(error && error.stack || error));
}
}
function ensure(condition, detail) {
if (!condition) throw new Error(detail);
}
async function setEditorSql(sql) {
await page.locator('#sql-editor').evaluate((node, value) => {
node.value = value;
node.dispatchEvent(new Event('input', { bubbles: true }));
node.dispatchEvent(new Event('change', { bubbles: true }));
}, sql);
}
page.on('console', (message) => {
consoleMessages.push(message.type() + ': ' + message.text());
});
page.on('pageerror', (error) => {
pageErrors.push(String(error && error.stack || error));
});
await page.goto(process.env.DASHBOARD_URL, { waitUntil: 'networkidle' });
await check('main tabs visible', async () => {
const tabs = await page.locator('[data-sql-main-tab]').allTextContents();
ensure(tabs.includes('Connection Profiles') && tabs.includes('SQL Workspace') && tabs.includes('Schema Explorer'),
'expected Connection Profiles, SQL Workspace, and Schema Explorer tabs: ' + JSON.stringify(tabs));
});
await check('profiles tab is default active', async () => {
const activeTab = await page.locator('[data-sql-main-tab].is-active').textContent();
ensure(String(activeTab || '').includes('Connection Profiles'), 'profiles tab should start active: ' + JSON.stringify({ activeTab }));
});
await check('legacy collections top tab removed', async () => {
const tabs = await page.locator('[data-sql-main-tab]').allTextContents();
ensure(!tabs.includes('SQL Collections'), 'legacy SQL Collections main tab should be gone: ' + JSON.stringify(tabs));
});
( run in 1.945 second using v1.01-cache-2.11-cpan-39bf76dae61 )