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
190 changes: 190 additions & 0 deletions e2e/tests/ssls.crud-all-fields.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 { sslsPom } from '@e2e/pom/ssls';
import { genTLS } from '@e2e/utils/common';
import { e2eReq } from '@e2e/utils/req';
import { test } from '@e2e/utils/test';
import { uiHasToastMsg } from '@e2e/utils/ui';
import { uiCheckLabels } from '@e2e/utils/ui/labels';
import { uiFillSSLRequiredFields } from '@e2e/utils/ui/ssls';
import { expect } from '@playwright/test';

import { deleteAllSSLs } from '@/apis/ssls';
import type { APISIXType } from '@/types/schema/apisix';

const snis = [
'full-test.example.com',
'www.full-test.example.com',
'api.full-test.example.com',
];
const { cert, key } = genTLS();

const initialLabels = {
env: 'production',
version: 'v1',
team: 'backend',
};

const sslDataAllFields: Partial<APISIXType['SSL']> = {
snis,
cert,
key,
labels: initialLabels,
status: 1, // Enabled
};

test.beforeAll(async () => {
await deleteAllSSLs(e2eReq);
});

test('should CRUD SSL with all fields', async ({ page }) => {
test.slow();

await sslsPom.toIndex(page);
await sslsPom.isIndexPage(page);

await sslsPom.getAddSSLBtn(page).click();
await sslsPom.isAddPage(page);

await test.step('fill in all fields', async () => {
// Fill in required fields
await uiFillSSLRequiredFields(page, sslDataAllFields);

// Set Status to Enabled
const statusField = page.getByRole('textbox', {
name: 'Status',
exact: true,
});
await statusField.click();
await page.getByRole('option', { name: 'Enabled' }).click();
await expect(statusField).toHaveValue('Enabled');

// Add SSL Protocols
const sslProtocolsField = page.getByRole('textbox', {
name: 'SSL Protocols',
});
await sslProtocolsField.click();
await page.getByRole('option', { name: 'TLSv1.2' }).click();
await page.getByRole('option', { name: 'TLSv1.3' }).click();
await page.keyboard.press('Escape');

// Verify protocols are selected
const protocolsContainer = sslProtocolsField.locator('..');
await expect(protocolsContainer).toContainText('TLSv1.2');
await expect(protocolsContainer).toContainText('TLSv1.3');

// Submit the form
await sslsPom.getAddBtn(page).click();
await uiHasToastMsg(page, {
hasText: 'Add SSL Successfully',
});

// Navigate back to list
await sslsPom.isIndexPage(page);
});

await test.step('navigate to detail and verify all fields', async () => {
// Click View to go to detail page
const firstSni = snis[0];
await page
.getByRole('row', { name: firstSni })
.getByRole('button', { name: 'View' })
.click();
await sslsPom.isDetailPage(page);

// Verify ID exists
const ID = page.getByRole('textbox', { name: 'ID', exact: true });
await expect(ID).toBeVisible();
await expect(ID).toBeDisabled();

// Verify SNIs
for (const sniValue of snis) {
await expect(page.getByText(sniValue, { exact: true })).toBeVisible();
}

// Verify certificate
const cert1Field = page.getByRole('textbox', { name: 'Certificate 1' });
await expect(cert1Field).toBeVisible();
await expect(cert1Field).toBeDisabled();

// Verify Status
const statusField = page.getByRole('textbox', {
name: 'Status',
exact: true,
});
await expect(statusField).toHaveValue('Enabled');

// Verify SSL Protocols
const protocolsField = page.getByRole('textbox', {
name: 'SSL Protocols',
});
const protocolsContainer = protocolsField.locator('..');
await expect(protocolsContainer).toContainText('TLSv1.2');
await expect(protocolsContainer).toContainText('TLSv1.3');

// Verify Labels
await uiCheckLabels(page, initialLabels);
});

await test.step('verify can enter edit mode', async () => {
// Click the Edit button
await page.getByRole('button', { name: 'Edit' }).click();

// Verify we're in edit mode
const cert1Field = page.getByRole('textbox', { name: 'Certificate 1' });
await expect(cert1Field).toBeEnabled();

// Cancel without making changes
await page.getByRole('button', { name: 'Cancel' }).click();

// Return to list page
await sslsPom.getSSLNavBtn(page).click();
await sslsPom.isIndexPage(page);
});

await test.step('delete SSL in detail page', async () => {
// Navigate to detail page
const firstSni = snis[0];
await page
.getByRole('row', { name: firstSni })
.getByRole('button', { name: 'View' })
.click();
await sslsPom.isDetailPage(page);

// Delete the SSL
await page.getByRole('button', { name: 'Delete' }).click();

await page
.getByRole('dialog', { name: 'Delete SSL' })
.getByRole('button', { name: 'Delete' })
.click();

// Will redirect to SSLs page
await sslsPom.isIndexPage(page);
await uiHasToastMsg(page, {
hasText: 'Delete SSL Successfully',
});
await expect(page.getByRole('cell', { name: firstSni })).toBeHidden();

// Final verification: Reload the page and check again
await page.reload();
await sslsPom.isIndexPage(page);

// After reload, the SSL should still be gone
await expect(page.getByRole('cell', { name: firstSni })).toBeHidden();
});
});
157 changes: 157 additions & 0 deletions e2e/tests/ssls.crud-required-fields.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 { sslsPom } from '@e2e/pom/ssls';
import { genTLS } from '@e2e/utils/common';
import { e2eReq } from '@e2e/utils/req';
import { test } from '@e2e/utils/test';
import { uiHasToastMsg } from '@e2e/utils/ui';
import { uiFillSSLRequiredFields } from '@e2e/utils/ui/ssls';
import { expect } from '@playwright/test';

import { deleteAllSSLs } from '@/apis/ssls';
import type { APISIXType } from '@/types/schema/apisix';

const snis = ['test.example.com', 'www.test.example.com'];
const { cert, key } = genTLS();
const sslData: Partial<APISIXType['SSL']> = {
snis,
cert,
key,
};

test.beforeAll(async () => {
await deleteAllSSLs(e2eReq);
});

test('should CRUD SSL with required fields', async ({ page }) => {
await sslsPom.toIndex(page);
await sslsPom.isIndexPage(page);

await sslsPom.getAddSSLBtn(page).click();
await sslsPom.isAddPage(page);

await test.step('submit with required fields', async () => {
// Fill in the required fields
await uiFillSSLRequiredFields(page, sslData);

// Submit the form
await sslsPom.getAddBtn(page).click();
await uiHasToastMsg(page, {
hasText: 'Add SSL Successfully',
});

// After creation, navigate back to list
await sslsPom.isIndexPage(page);
});

await test.step('SSL should exist in list page and navigate to detail', async () => {
// Verify SSL exists in list
const firstSni = snis[0];
await expect(page.getByRole('cell', { name: firstSni })).toBeVisible();

// Click on the View button to go to the detail page
await page
.getByRole('row', { name: firstSni })
.getByRole('button', { name: 'View' })
.click();
await sslsPom.isDetailPage(page);
});

await test.step('verify SSL details', async () => {

// Verify the SSL details
// Verify ID exists
const ID = page.getByRole('textbox', { name: 'ID', exact: true });
await expect(ID).toBeVisible();
await expect(ID).toBeDisabled();

// Verify SNIs are displayed
for (const sniValue of snis) {
await expect(page.getByText(sniValue, { exact: true })).toBeVisible();
}

// Verify certificate and key fields are displayed (key might be empty for security)
const certField = page.getByRole('textbox', { name: 'Certificate 1' });
await expect(certField).toBeVisible();
await expect(certField).toBeDisabled();

const keyField = page.getByRole('textbox', { name: 'Private Key 1' });
await expect(keyField).toBeVisible();
await expect(keyField).toBeDisabled();
});

await test.step('edit and update SSL in detail page', async () => {
// Click the Edit button in the detail page
await page.getByRole('button', { name: 'Edit' }).click();

// Verify we're in edit mode - fields should be editable now
const certField = page.getByRole('textbox', { name: 'Certificate 1' });
await expect(certField).toBeEnabled();

// Update SNIs - add a new one
const snisField = page.getByRole('textbox', { name: 'SNIs' });
await snisField.click();
await snisField.fill('updated.example.com');
await snisField.press('Enter');
await expect(snisField).toHaveValue('');

// Verify the new SNI is displayed
await expect(page.getByText('updated.example.com', { exact: true })).toBeVisible();

// Click Cancel instead of Save to avoid validation issues with empty key
await page.getByRole('button', { name: 'Cancel' }).click();

// Verify we're back in detail view mode
await sslsPom.isDetailPage(page);

// Return to list page and verify the SSL exists
await sslsPom.getSSLNavBtn(page).click();
await sslsPom.isIndexPage(page);

// Find the row with our SSL (by first SNI)
const firstSni = snis[0];
const row = page.getByRole('row', { name: firstSni });
await expect(row).toBeVisible();
});

await test.step('delete SSL from list page', async () => {
await sslsPom.getSSLNavBtn(page).click();
await sslsPom.isIndexPage(page);

// Click on the View button to go to the detail page
await page
.getByRole('row', { name: snis[0] })
.getByRole('button', { name: 'View' })
.click();
await sslsPom.isDetailPage(page);

// Delete the SSL
await page.getByRole('button', { name: 'Delete' }).click();

await page
.getByRole('dialog', { name: 'Delete SSL' })
.getByRole('button', { name: 'Delete' })
.click();

// Will redirect to SSLs page
await sslsPom.isIndexPage(page);
await uiHasToastMsg(page, {
hasText: 'Delete SSL Successfully',
});
await expect(page.getByRole('cell', { name: snis[0] })).toBeHidden();
});
});
Loading
Loading