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§ion=${ 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§ion=${ 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