blob: 5a02c87f388293908232d0e68209225111bc50cd [file]
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { expect, test } from '@playwright/test';
import { BasePage } from '../models/base-page';
import { LoginTestUtil } from '../models/login-page.util';
import { addPageAnnotationBeforeEach, waitForZeppelinReady, PAGES } from '../utils';
test.describe('Zeppelin App Component', () => {
addPageAnnotationBeforeEach(PAGES.APP);
let basePage: BasePage;
test.beforeEach(async ({ page }) => {
basePage = new BasePage(page);
await page.goto('/', { waitUntil: 'load' });
});
test('should have correct component selector and structure', async ({ page }) => {
await basePage.waitForPageLoad();
// Test zeppelin-root selector
const zeppelinRoot = page.locator('zeppelin-root');
await expect(zeppelinRoot).toBeAttached();
await waitForZeppelinReady(page);
// Verify router-outlet is inside zeppelin-root (use first to avoid multiple elements)
const routerOutlet = zeppelinRoot.locator('router-outlet').first();
await expect(routerOutlet).toBeAttached();
// Check for loading spinner
const loadingSpinner = zeppelinRoot.locator('zeppelin-spin').filter({ hasText: 'Getting Ticket Data' });
const logoutSpinner = zeppelinRoot.locator('zeppelin-spin').filter({ hasText: 'Logging out' });
// Loading spinner should exist, logout spinner may or may not exist depending on conditions
const loadingSpinnerCount = await loadingSpinner.count();
const logoutSpinnerCount = await logoutSpinner.count();
expect(loadingSpinnerCount).toBeGreaterThanOrEqual(0);
expect(logoutSpinnerCount).toBeGreaterThanOrEqual(0);
});
test('should have proper page title', async ({ page }) => {
await expect(page).toHaveTitle(/Zeppelin/);
});
test('should display workspace after loading', async ({ page }) => {
await waitForZeppelinReady(page);
const isShiroEnabled = await LoginTestUtil.isShiroEnabled();
if (isShiroEnabled) {
await expect(page.locator('zeppelin-login')).toBeVisible();
} else {
await expect(page.locator('zeppelin-workspace')).toBeVisible();
}
});
test('should handle navigation events correctly', async ({ page }) => {
await waitForZeppelinReady(page);
// Test navigation back to root path
try {
await page.goto('/', { waitUntil: 'load', timeout: 10000 });
// Check if loading spinner appears during navigation
const loadingSpinner = page.locator('zeppelin-spin').filter({ hasText: 'Getting Ticket Data' });
// Loading might be very fast, so we check if it exists
const spinnerCount = await loadingSpinner.count();
expect(spinnerCount).toBeGreaterThanOrEqual(0);
await waitForZeppelinReady(page);
// After ready, loading should be hidden if it was visible
if (await loadingSpinner.isVisible()) {
await expect(loadingSpinner).toBeHidden();
}
} catch (error) {
console.log('Navigation test skipped due to timeout:', error);
}
});
test('should properly manage loading state observable', async ({ page }) => {
await basePage.waitForPageLoad();
// Test that loading$ observable works correctly
const loadingSpinner = page.locator('zeppelin-spin').filter({ hasText: 'Getting Ticket Data' });
// Reload page to trigger loading state
await page.reload({ waitUntil: 'load' });
// Check loading state during page load
const initialLoadingVisible = await loadingSpinner.isVisible();
if (initialLoadingVisible) {
await expect(loadingSpinner).toBeVisible();
await expect(loadingSpinner).toContainText('Getting Ticket Data ...');
}
// Wait for loading to complete
await waitForZeppelinReady(page);
await expect(loadingSpinner).toBeHidden();
});
test('should handle logout observable correctly', async ({ page }) => {
await waitForZeppelinReady(page);
const logoutSpinner = page.locator('zeppelin-spin').filter({ hasText: 'Logging out' });
// Initially logout spinner should be hidden
await expect(logoutSpinner).toBeHidden();
// Check if we have a logout mechanism available
const statusElement = page.locator('.status');
if (await statusElement.isVisible()) {
const statusText = await statusElement.textContent();
if (statusText && !statusText.includes('anonymous')) {
// If not anonymous user, test logout spinner
await statusElement.click();
const logoutButton = page.getByRole('link', { name: 'Logout' });
if (await logoutButton.isVisible()) {
await logoutButton.click();
// Logout spinner should appear
await expect(logoutSpinner).toBeVisible();
await expect(logoutSpinner).toContainText('Logging out ...');
}
}
}
});
test('should maintain component integrity during navigation', async ({ page }) => {
await waitForZeppelinReady(page);
const zeppelinRoot = page.locator('zeppelin-root');
const routerOutlet = zeppelinRoot.locator('router-outlet').first();
// Navigate to different pages and ensure component remains intact
const testPaths = ['/#/notebook', '/#/jobmanager', '/#/configuration'];
for (const path of testPaths) {
await page.goto(path, { waitUntil: 'load', timeout: 10000 });
await waitForZeppelinReady(page);
// Component should still be attached
await expect(zeppelinRoot).toBeAttached();
// Router outlet should still be present
await expect(routerOutlet).toBeAttached();
}
// Return to home
await page.goto('/', { waitUntil: 'load' });
await waitForZeppelinReady(page);
await expect(zeppelinRoot).toBeAttached();
});
test('should verify spinner text content and visibility', async ({ page }) => {
await basePage.waitForPageLoad();
// Check exact text content of spinners
const loadingSpinner = page.locator('zeppelin-spin').filter({ hasText: 'Getting Ticket Data' });
const logoutSpinner = page.locator('zeppelin-spin').filter({ hasText: 'Logging out' });
// Verify spinner elements exist
expect(await loadingSpinner.count()).toBeGreaterThanOrEqual(0);
expect(await logoutSpinner.count()).toBeGreaterThanOrEqual(0);
// If loading spinner is visible, check its exact text
if (await loadingSpinner.isVisible()) {
await expect(loadingSpinner).toHaveText('Getting Ticket Data ...');
}
// Logout spinner should not be visible initially
await expect(logoutSpinner).toBeHidden();
});
});