Skip to content

Commit cf6615a

Browse files
committed
Add api key and method visibility tests
1 parent 80909a4 commit cf6615a

File tree

5 files changed

+778
-1
lines changed

5 files changed

+778
-1
lines changed

playwright.config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ export default defineConfig({
3535
use: { ...devices['Desktop Chrome'] },
3636
testMatch: '**/payment-gateway-matrix.spec.ts',
3737
},
38+
{
39+
name: 'api-key-tests',
40+
dependencies: ['setup'],
41+
use: { ...devices['Desktop Chrome'] },
42+
testMatch: '**/monei-settings-api.spec.ts',
43+
workers: 1
44+
},
3845
],
3946

4047
/* Run your local dev server before starting the tests */

tests/fixtures/user-types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ export const USER_TYPES: Record<string, UserType> = {
2929
city: 'Lisbon',
3030
postcode: '1100-053',
3131
country: 'PT',
32-
state: 'Lisboa',
3332
phone: '+351912345678',
3433
email: 'joao.silva@example.com'
3534
},
Lines changed: 326 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,326 @@
1+
import { Page, expect } from '@playwright/test';
2+
import { MoneiSettingsPage } from '../pages/admin/monei-settings-page';
3+
4+
/**
5+
* Admin Test Helpers for WordPress/WooCommerce administration
6+
*/
7+
export class AdminTestHelpers {
8+
readonly page: Page;
9+
10+
constructor(page: Page) {
11+
this.page = page;
12+
}
13+
14+
/**
15+
* Feature: WordPress admin authentication
16+
* Scenario: Admin logs into WordPress dashboard
17+
* Given the admin has valid credentials
18+
* When the admin navigates to wp-admin
19+
* And enters valid credentials
20+
* Then the admin should be logged in successfully
21+
*/
22+
async loginAsAdmin(username?: string, password?: string) {
23+
const adminUser = username || process.env.WORDPRESS_ADMIN_USER || 'admin';
24+
const adminPassword = password || process.env.WORDPRESS_ADMIN_PASSWORD || 'password';
25+
26+
await this.page.goto('/wp-admin');
27+
28+
if (await this.page.locator('#wpadminbar').isVisible()) {
29+
console.log('Already logged in as admin');
30+
return;
31+
}
32+
33+
await this.page.fill('#user_login', adminUser);
34+
await this.page.fill('#user_pass', adminPassword);
35+
await this.page.click('#wp-submit');
36+
37+
await this.page.waitForURL('/wp-admin/', { timeout: 10000 });
38+
await expect(this.page.locator('#wpadminbar')).toBeVisible();
39+
console.log('✅ Successfully logged in as admin');
40+
}
41+
42+
/**
43+
* Feature: WordPress admin logout
44+
* Scenario: Admin logs out from WordPress dashboard
45+
* Given the admin is logged in
46+
* When the admin clicks on the logout link
47+
* Then the admin should be logged out successfully
48+
*/
49+
async logoutAsAdmin() {
50+
if (await this.page.locator('#wpadminbar').isVisible()) {
51+
await this.page.hover('#wp-admin-bar-my-account');
52+
await this.page.click('#wp-admin-bar-logout a');
53+
await this.page.waitForLoadState('networkidle');
54+
55+
const isAdminBarVisible = await this.page.locator('#wpadminbar').isVisible().catch(() => false);
56+
if (!isAdminBarVisible) {
57+
console.log('✅ Successfully logged out from admin account');
58+
} else {
59+
console.warn('⚠️ Logout may not have completed successfully');
60+
}
61+
} else {
62+
console.log('ℹ️ Already logged out');
63+
}
64+
}
65+
66+
/**
67+
* Feature: WooCommerce settings navigation
68+
* Scenario: Admin navigates to WooCommerce settings
69+
* Given the admin is logged in
70+
* When the admin navigates to WooCommerce settings
71+
* Then the WooCommerce settings page should load
72+
*/
73+
async navigateToWooCommerceSettings() {
74+
await this.page.goto('/wp-admin/admin.php?page=wc-settings');
75+
await expect(this.page.locator('.wc-settings-navigation')).toBeVisible();
76+
}
77+
78+
/**
79+
* Feature: MONEI settings navigation
80+
* Scenario: Admin navigates to MONEI settings
81+
* Given the admin is logged in
82+
* When the admin navigates to MONEI settings
83+
* Then the MONEI settings page should load
84+
*/
85+
async navigateToMoneiSettings() {
86+
await this.page.goto('/wp-admin/admin.php?page=wc-settings&tab=monei_settings');
87+
await expect(this.page.locator('.monei-settings-header-logo')).toBeVisible();
88+
}
89+
90+
/**
91+
* Feature: Payment method configuration
92+
* Scenario: Admin activates a specific payment method
93+
* Given the admin is on the payment settings page
94+
* When the admin enables a payment method
95+
* And saves the configuration
96+
* Then the payment method should be activated
97+
*/
98+
async activatePaymentMethod(methodId: string, customSettings?: Record<string, any>) {
99+
await this.page.goto(`/wp-admin/admin.php?page=wc-settings&tab=checkout&section=${methodId}`);
100+
101+
// Wait for the settings form to load
102+
await this.page.waitForSelector(`#woocommerce_${methodId}_enabled`, { timeout: 5000 });
103+
104+
// Enable the payment method
105+
const enableCheckbox = this.page.locator(`#woocommerce_${methodId}_enabled`);
106+
const isEnabled = await enableCheckbox.isChecked();
107+
108+
if (!isEnabled) {
109+
await enableCheckbox.check();
110+
}
111+
112+
// Apply custom settings if provided
113+
if (customSettings) {
114+
for (const [settingKey, value] of Object.entries(customSettings)) {
115+
const selector = `#woocommerce_${methodId}_${settingKey}`;
116+
const element = this.page.locator(selector);
117+
118+
if (await element.isVisible()) {
119+
const elementType = await element.getAttribute('type');
120+
121+
if (elementType === 'checkbox') {
122+
if (value) {
123+
await element.check();
124+
} else {
125+
await element.uncheck();
126+
}
127+
} else if (await element.evaluate(el => el.tagName.toLowerCase()) === 'select') {
128+
await element.selectOption(value);
129+
} else {
130+
await element.fill(value);
131+
}
132+
}
133+
}
134+
}
135+
136+
// Save the settings
137+
await this.page.click('button[name="save"]');
138+
await expect(this.page.locator('.updated.inline')).toBeVisible({ timeout: 10000 });
139+
140+
console.log(`✅ Payment method ${methodId} activated successfully`);
141+
}
142+
143+
/**
144+
* Feature: Payment method validation
145+
* Scenario: Admin verifies payment method is properly configured
146+
* Given a payment method is activated
147+
* When the admin checks the payment method configuration
148+
* Then all required settings should be properly configured
149+
*/
150+
async verifyPaymentMethodConfiguration(methodId: string): Promise<boolean> {
151+
await this.page.goto(`/wp-admin/admin.php?page=wc-settings&tab=checkout&section=${methodId}`);
152+
153+
const isEnabled = await this.page.isChecked(`#woocommerce_${methodId}_enabled`);
154+
const hasTitle = await this.page.inputValue(`#woocommerce_${methodId}_title`);
155+
156+
console.log(`Payment method ${methodId} - Enabled: ${isEnabled}, Title: ${hasTitle}`);
157+
158+
return isEnabled && !!hasTitle;
159+
}
160+
161+
/**
162+
* Feature: Plugin management
163+
* Scenario: Admin activates the MONEI plugin
164+
* Given the MONEI plugin is installed
165+
* When the admin activates the plugin
166+
* Then the plugin should be active and settings should be accessible
167+
*/
168+
async activateMoneiPlugin() {
169+
await this.page.goto('/wp-admin/plugins.php');
170+
171+
const moneiPluginRow = this.page.locator('tr[data-plugin*="monei"]').first();
172+
const activateLink = moneiPluginRow.locator('a.activate');
173+
174+
if (await activateLink.isVisible()) {
175+
await activateLink.click();
176+
await expect(this.page.locator('.updated')).toBeVisible();
177+
console.log('✅ MONEI plugin activated successfully');
178+
} else {
179+
console.log('ℹ️ MONEI plugin is already active');
180+
}
181+
}
182+
183+
/**
184+
* Feature: Country configuration testing
185+
* Scenario: Admin tests payment methods for different countries
186+
* Given payment methods are configured
187+
* When the admin simulates different billing countries
188+
* Then country-specific payment methods should be available
189+
*/
190+
async getAvailablePaymentMethodsForCountry(countryCode: string): Promise<string[]> {
191+
await this.page.goto('/checkout/');
192+
await this.page.selectOption('#billing_country', countryCode);
193+
await this.page.waitForTimeout(2000); // Wait for AJAX to update payment methods
194+
195+
const paymentMethods = await this.page.locator('input[name="payment_method"]').all();
196+
const availableMethods = [];
197+
198+
for (const method of paymentMethods) {
199+
if (await method.isVisible()) {
200+
const value = await method.getAttribute('value');
201+
if (value) {
202+
availableMethods.push(value);
203+
}
204+
}
205+
}
206+
207+
return availableMethods;
208+
}
209+
210+
/**
211+
* Feature: Debug logging verification
212+
* Scenario: Admin verifies debug logging is working
213+
* Given debug logging is enabled
214+
* When payment events occur
215+
* Then events should be logged in WooCommerce logs
216+
*/
217+
async verifyDebugLogging(): Promise<boolean> {
218+
await this.page.goto('/wp-admin/admin.php?page=wc-status&tab=logs');
219+
220+
const logFiles = await this.page.locator('select[name="log_file"] option').all();
221+
222+
for (const option of logFiles) {
223+
const text = await option.textContent();
224+
if (text && text.includes('monei')) {
225+
console.log('✅ MONEI debug logs found');
226+
return true;
227+
}
228+
}
229+
230+
console.log('ℹ️ No MONEI debug logs found yet');
231+
return false;
232+
}
233+
234+
/**
235+
* Feature: API key validation
236+
* Scenario: Admin validates API keys are working
237+
* Given API keys are configured
238+
* When the admin saves the settings
239+
* Then the keys should be validated against MONEI API
240+
*/
241+
async validateApiKeys(accountId: string, apiKey: string): Promise<boolean> {
242+
await this.navigateToMoneiSettings();
243+
244+
await this.page.selectOption(MoneiSettingsPage.apiKeyModeSelect , 'test');
245+
await this.page.fill(MoneiSettingsPage.testAccountIdInput, accountId);
246+
await this.page.fill(MoneiSettingsPage.testApiKeyInput, apiKey);
247+
248+
await this.page.click(MoneiSettingsPage.saveChangesButton);
249+
250+
const hasError = await this.page.locator('.error').isVisible();
251+
const hasSuccess = await this.page.locator('.updated.inline').isVisible();
252+
253+
if (hasError) {
254+
const errorText = await this.page.locator('.error').textContent();
255+
console.log(`❌ API key validation failed: ${errorText}`);
256+
return false;
257+
}
258+
259+
if (hasSuccess) {
260+
console.log('✅ API keys validated successfully');
261+
return true;
262+
}
263+
264+
console.log('⚠️ API key validation status unclear');
265+
return false;
266+
}
267+
268+
/**
269+
* Feature: Cleanup utilities
270+
* Scenario: Admin cleans up test data
271+
* Given tests have been run
272+
* When cleanup is needed
273+
* Then test data should be removed
274+
*/
275+
async cleanupTestData() {
276+
await this.page.goto('/cart/');
277+
const removeButtons = await this.page.locator('.remove').all();
278+
for (const button of removeButtons) {
279+
await button.click();
280+
await this.page.waitForTimeout(1000);
281+
}
282+
283+
console.log('🧹 Test cleanup completed');
284+
}
285+
}
286+
287+
/**
288+
* Environment configuration helper
289+
*/
290+
export class TestEnvironmentHelper {
291+
/**
292+
* Validates that all required environment variables are set
293+
*/
294+
static validateEnvironment(): void {
295+
const required = [
296+
'TESTSITE_URL',
297+
'WORDPRESS_ADMIN_USER',
298+
'WORDPRESS_ADMIN_PASSWORD',
299+
'PAYMENT_GATEWAY_ACCOUNTID',
300+
'PAYMENT_GATEWAY_API_KEY'
301+
];
302+
303+
const missing = required.filter(env => !process.env[env]);
304+
305+
if (missing.length > 0) {
306+
throw new Error(`Missing required environment variables: ${missing.join(', ')}`);
307+
}
308+
}
309+
310+
/**
311+
* Gets test configuration from environment
312+
*/
313+
static getTestConfig() {
314+
this.validateEnvironment();
315+
316+
return {
317+
siteUrl: process.env.TESTSITE_URL,
318+
adminUser: process.env.WORDPRESS_ADMIN_USER,
319+
adminPassword: process.env.WORDPRESS_ADMIN_PASSWORD,
320+
accountId: process.env.PAYMENT_GATEWAY_ACCOUNTID,
321+
apiKey: process.env.PAYMENT_GATEWAY_API_KEY,
322+
wcConsumerKey: process.env.WC_CONSUMER_KEY,
323+
wcConsumerSecret: process.env.WC_CONSUMER_SECRET
324+
};
325+
}
326+
}

0 commit comments

Comments
 (0)