Regenerate screenshots and bump version
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
A modern web hosting control panel for WordPress and general PHP hosting. Built with Laravel 12, Filament v5, Livewire 4, and Tailwind CSS v4.
|
A modern web hosting control panel for WordPress and general PHP hosting. Built with Laravel 12, Filament v5, Livewire 4, and Tailwind CSS v4.
|
||||||
|
|
||||||
Version: 0.9-rc (initial release)
|
Version: 0.9-rc1 (release candidate)
|
||||||
|
|
||||||
This is a release candidate. Expect rapid iteration and breaking changes until 1.0.
|
This is a release candidate. Expect rapid iteration and breaking changes until 1.0.
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 404 KiB After Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 176 KiB After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 140 KiB |
@@ -14,7 +14,7 @@ class VersionFileTest extends TestCase
|
|||||||
$content = file_get_contents($versionPath);
|
$content = file_get_contents($versionPath);
|
||||||
|
|
||||||
$this->assertNotFalse($content);
|
$this->assertNotFalse($content);
|
||||||
$this->assertStringContainsString('VERSION=0.9-rc', $content);
|
$this->assertStringContainsString('VERSION=0.9-rc1', $content);
|
||||||
$this->assertStringNotContainsString('BUILD=', $content);
|
$this->assertStringNotContainsString('BUILD=', $content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,11 @@ const hasFlag = (flag) => args.includes(`--${flag}`);
|
|||||||
let browser;
|
let browser;
|
||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
|
const viewportWidth = Number(getArg('viewport-width', '1400'));
|
||||||
|
const viewportHeight = Number(getArg('viewport-height', '800'));
|
||||||
|
const fullPage = hasFlag('full-page');
|
||||||
|
const impersonateUserId = getArg('impersonate-user-id', null);
|
||||||
|
|
||||||
const CONFIG = {
|
const CONFIG = {
|
||||||
baseUrl: getArg('base-url', 'https://mx.jabali-panel.com'),
|
baseUrl: getArg('base-url', 'https://mx.jabali-panel.com'),
|
||||||
adminPath: getArg('admin-path', '/jabali-admin'),
|
adminPath: getArg('admin-path', '/jabali-admin'),
|
||||||
@@ -34,10 +39,11 @@ const CONFIG = {
|
|||||||
email: getArg('user-email', 'user@jabali-panel.com'),
|
email: getArg('user-email', 'user@jabali-panel.com'),
|
||||||
password: getArg('user-password', 'PycpS1dUuLvxMMQs')
|
password: getArg('user-password', 'PycpS1dUuLvxMMQs')
|
||||||
},
|
},
|
||||||
viewport: { width: 1400, height: 900 },
|
viewport: { width: viewportWidth, height: viewportHeight },
|
||||||
outputDir: getArg('output-dir', '/tmp'),
|
outputDir: getArg('output-dir', '/tmp'),
|
||||||
skipAdmin: hasFlag('skip-admin'),
|
skipAdmin: hasFlag('skip-admin'),
|
||||||
skipUser: hasFlag('skip-user')
|
skipUser: hasFlag('skip-user'),
|
||||||
|
impersonateUserId
|
||||||
};
|
};
|
||||||
|
|
||||||
// Admin pages to screenshot
|
// Admin pages to screenshot
|
||||||
@@ -63,12 +69,7 @@ const USER_PAGES = [
|
|||||||
|
|
||||||
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
|
||||||
async function capturePanel({ panelName, basePath, credentials, pages, outputPrefix }) {
|
async function loginPanel(page, panelName, basePath, credentials) {
|
||||||
const context = await browser.createBrowserContext();
|
|
||||||
const page = await context.newPage();
|
|
||||||
await page.setViewport(CONFIG.viewport);
|
|
||||||
|
|
||||||
try {
|
|
||||||
console.log(`Logging in to ${panelName} panel...`);
|
console.log(`Logging in to ${panelName} panel...`);
|
||||||
await page.goto(`${CONFIG.baseUrl}${basePath}/login`, { waitUntil: 'networkidle0' });
|
await page.goto(`${CONFIG.baseUrl}${basePath}/login`, { waitUntil: 'networkidle0' });
|
||||||
await wait(1500);
|
await wait(1500);
|
||||||
@@ -83,6 +84,38 @@ async function capturePanel({ panelName, basePath, credentials, pages, outputPre
|
|||||||
throw new Error(`${panelName} login failed - still on login page`);
|
throw new Error(`${panelName} login failed - still on login page`);
|
||||||
}
|
}
|
||||||
console.log(`${panelName} login successful!\n`);
|
console.log(`${panelName} login successful!\n`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loginUserViaImpersonation(page) {
|
||||||
|
if (!CONFIG.impersonateUserId) {
|
||||||
|
throw new Error('Missing --impersonate-user-id for user screenshots');
|
||||||
|
}
|
||||||
|
|
||||||
|
await loginPanel(page, 'Admin', CONFIG.adminPath, CONFIG.admin);
|
||||||
|
|
||||||
|
const impersonateUrl = `${CONFIG.baseUrl}/impersonate/start/${CONFIG.impersonateUserId}`;
|
||||||
|
console.log(`Impersonating user via: ${impersonateUrl}`);
|
||||||
|
await page.goto(impersonateUrl, { waitUntil: 'networkidle0' });
|
||||||
|
await wait(2000);
|
||||||
|
|
||||||
|
const currentUrl = page.url();
|
||||||
|
if (currentUrl.includes('/login')) {
|
||||||
|
throw new Error('Impersonation failed - still on login page');
|
||||||
|
}
|
||||||
|
console.log('User impersonation successful!\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function capturePanel({ panelName, basePath, credentials, pages, outputPrefix }) {
|
||||||
|
const context = await browser.createBrowserContext();
|
||||||
|
const page = await context.newPage();
|
||||||
|
await page.setViewport(CONFIG.viewport);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (panelName === 'User' && CONFIG.impersonateUserId) {
|
||||||
|
await loginUserViaImpersonation(page);
|
||||||
|
} else {
|
||||||
|
await loginPanel(page, panelName, basePath, credentials);
|
||||||
|
}
|
||||||
|
|
||||||
for (const pageInfo of pages) {
|
for (const pageInfo of pages) {
|
||||||
const url = `${CONFIG.baseUrl}${basePath}${pageInfo.path}`;
|
const url = `${CONFIG.baseUrl}${basePath}${pageInfo.path}`;
|
||||||
@@ -95,7 +128,7 @@ async function capturePanel({ panelName, basePath, credentials, pages, outputPre
|
|||||||
try {
|
try {
|
||||||
await page.goto(url, { waitUntil: 'networkidle0', timeout: 30000 });
|
await page.goto(url, { waitUntil: 'networkidle0', timeout: 30000 });
|
||||||
await wait(3000);
|
await wait(3000);
|
||||||
await page.screenshot({ path: filepath, fullPage: true });
|
await page.screenshot({ path: filepath, fullPage });
|
||||||
console.log(` Saved: ${filepath}\n`);
|
console.log(` Saved: ${filepath}\n`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(` Error: ${err.message}\n`);
|
console.log(` Error: ${err.message}\n`);
|
||||||
|
|||||||