Skip to content

Commit a86644e

Browse files
authored
Merge branch 'gambitph:develop' into patch-18
2 parents 9d275b4 + d0c6b96 commit a86644e

File tree

141 files changed

+11793
-3981
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

141 files changed

+11793
-3981
lines changed

.config/webpack.config.dev.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,6 @@ module.exports = [
2626
},
2727
// Admin settings script.
2828
'admin_welcome': path.resolve( __dirname, '../src/welcome/admin.js' ),
29-
// V2 deprecated scripts, we build this here since that's how we did it before.
30-
'admin_welcome_v2': {
31-
import: path.resolve( __dirname, '../src/deprecated/v2/welcome/admin.js' ),
32-
filename: 'deprecated/[name].js'
33-
},
3429
'frontend_blocks_deprecated_v2': {
3530
import: path.resolve( __dirname, '../src/deprecated/v2/block-frontend.js' ),
3631
filename: 'deprecated/[name].js'
@@ -39,6 +34,7 @@ module.exports = [
3934

4035
output: {
4136
filename: '[name].js',
37+
chunkFilename: '[name].[contenthash].json', // Output filename for dynamically imported chunks
4238
},
4339

4440
// Externals are only WordPress loaded libraries.

.config/webpack.config.prod.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,6 @@ module.exports = [
2626
},
2727
// Admin settings script.
2828
'admin_welcome': path.resolve( __dirname, '../src/welcome/admin.js' ),
29-
// V2 deprecated script, we build this here since that's how we did it before.
30-
'admin_welcome_v2': {
31-
import: path.resolve( __dirname, '../src/deprecated/v2/welcome/admin.js' ),
32-
filename: 'deprecated/[name].js'
33-
},
3429
'frontend_blocks_deprecated_v2': {
3530
import: path.resolve( __dirname, '../src/deprecated/v2/block-frontend.js' ),
3631
filename: 'deprecated/[name].js'
@@ -39,6 +34,7 @@ module.exports = [
3934

4035
output: {
4136
filename: '[name].js',
37+
chunkFilename: '[name].[contenthash].json', // Output filename for dynamically imported chunks
4238
},
4339

4440
// Externals are only WordPress loaded libraries.

.github/workflows/playwright.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,20 @@ jobs:
1313
matrix:
1414
include:
1515
- php_version: '7.3'
16-
wp_version: 6.4.5
16+
wp_version: 6.5.5
1717

1818
- php_version: '7.3'
1919
wp_version: null
2020

21-
- php_version: '8.2'
22-
wp_version: 6.4.5
23-
2421
- php_version: '8.2'
2522
wp_version: 6.5.5
2623

2724
- php_version: '8.2'
2825
wp_version: 6.6.2
2926

27+
- php_version: '8.2'
28+
wp_version: 6.7.2
29+
3030
- php_version: '8.2'
3131
wp_version: null
3232

@@ -71,6 +71,8 @@ jobs:
7171
npm install -g @wordpress/env
7272
- name: Start wp-env
7373
run: wp-env start
74+
- name: Print current WP version
75+
run: wp-env run tests-cli wp core version
7476
- name: Create post with existing blocks
7577
run: |
7678
POST_ID=$(wp-env run tests-cli wp post create wp-content/plugins/Stackable/e2e/config/post-content.txt --post_title="Existing Blocks" --post_status=publish --porcelain)

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@
1111
"css",
1212
"scss"
1313
]
14-
}
14+
}

e2e/readme.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,17 @@ WP_BASE_URL=http://local.local/
3232
WP_AUTH_STORAGE=wp-auth.json
3333
WP_USERNAME=admin
3434
WP_PASSWORD=password
35+
STACKABLE_SLUG={ STACKABLE SLUG }
36+
WP_TEST_POSTID={ POST_ID }
37+
WP_STK_LICENSE={ STACKABLE LICENSE }
3538
```
3639

40+
In Freemius, make sure the license key is:
41+
- new
42+
- lifetime unlimited quota
43+
- has an owner
44+
- non-blocking and white-labeled
45+
3746
Run this command to run e2e:
3847

3948
```bash

e2e/test-utils/stackable.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,9 @@ export class StackableFixture {
88
this.page = page
99
}
1010

11-
// When loading the Stackable settings in the Admin, there are 4 requests to wp/v2/settings
12-
// This function waits for all 4 requests to finish to ensure Stackable settings are loaded and reflected on the page
11+
// Wait for Stackable Settings to be fetched
1312
async waitForSettings(): Promise<void> {
1413
return new Promise( ( resolve, reject ) => {
15-
let responseCount = 0
16-
1714
const cleanup = () => {
1815
this.page.off( 'requestfinished', finishedCallback )
1916
this.page.off( 'requestfinished', failedCallback )
@@ -29,14 +26,10 @@ export class StackableFixture {
2926
} )
3027

3128
if ( settings ) {
32-
responseCount++
33-
} else {
34-
throw Error( 'Failed to get Stackable settings' )
35-
}
36-
37-
if ( responseCount === 4 ) {
3829
cleanup()
3930
resolve()
31+
} else {
32+
throw Error( 'Failed to get Stackable settings' )
4033
}
4134
} catch ( error ) {
4235
cleanup()

e2e/tests/admin.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ test( 'Stackable settings should be saved', async ( {
4040
// Make sure all Stackable settings are loaded
4141
await settings
4242

43+
// There should be no PHP errors
44+
const pageError = await admin.getPageError()
45+
expect( pageError ).toBeNull()
46+
4347
// Retrieves the value of the first option, toggles it and check if the value changed
4448
const option = page.locator( '.ugb-admin-toggle-setting' ).first().getByRole( 'switch' )
4549
const val = await option.getAttribute( 'aria-checked' )

e2e/tests/block-editor.spec.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,14 @@ test.describe( 'Block Editor', () => {
2424
} ) => {
2525
// Insert Stackable Text Block through block inserter
2626
// Also checks if Stackable Block is in the list of blocks in the Editor
27-
await page.getByLabel( 'Toggle block inserter' ).click()
27+
if ( await page.getByLabel( 'Toggle block inserter' ).isVisible() ) {
28+
// For WP version 6.7 and below
29+
await page.getByLabel( 'Toggle block inserter' ).click()
30+
} else {
31+
// For WP version 6.8
32+
await page.getByLabel( 'Block Inserter' ).click()
33+
}
34+
2835
await page.locator( '.editor-block-list-item-stackable-text' ).click()
2936

3037
await expect( editor.canvas.getByLabel( 'Block: Text' ) ).toBeVisible()
@@ -39,6 +46,13 @@ test.describe( 'Block Editor', () => {
3946
} )
4047

4148
await editor.selectBlocks( editor.canvas.getByLabel( 'Block: Text' ) )
49+
50+
const settings = page.getByLabel( 'Settings', { exact: true } )
51+
52+
if ( await settings.getAttribute( 'aria-pressed' ) === 'false' ) {
53+
await settings.click()
54+
}
55+
4256
await expect( page.getByLabel( 'Layout Tab' ) ).toBeVisible()
4357
await expect( page.getByLabel( 'Style Tab' ) ).toBeVisible()
4458
await expect( page.getByLabel( 'Advanced Tab' ) ).toBeVisible()
@@ -52,6 +66,12 @@ test.describe( 'Block Editor', () => {
5266
name: 'stackable/text',
5367
} )
5468

69+
const settings = page.getByLabel( 'Settings', { exact: true } )
70+
71+
if ( await settings.getAttribute( 'aria-pressed' ) === 'false' ) {
72+
await settings.click()
73+
}
74+
5575
// Add content and color to Stackable Text Block
5676
await editor.canvas.locator( '[data-type="stackable/text"] > .stk-block-text > p[role="textbox"]' ).fill( 'test' )
5777
await page.locator( '.stk-color-palette-control .stk-control-content > .components-dropdown > .components-button' ).first().click()
@@ -79,7 +99,7 @@ test.describe( 'Block Editor', () => {
7999
} )
80100

81101
test( 'The Stackable block added in the editor should be visible in the frontend', async ( {
82-
page, editor,
102+
page, editor, admin,
83103
} ) => {
84104
await editor.insertBlock( {
85105
name: 'stackable/text',
@@ -111,5 +131,9 @@ test.describe( 'Block Editor', () => {
111131
await expect( preview.locator( `[data-block-id="${ uniqueId }"]` ) ).toBeVisible()
112132
await expect( preview.locator( `[data-block-id="${ uniqueId }"]` ) ).toContainText( 'test' )
113133
await expect( preview.locator( `[data-block-id="${ uniqueId }"] p` ) ).toHaveCSS( 'color', 'rgb(255, 0, 0)' )
134+
135+
// There should be no PHP errors on frontend
136+
const pageError = await admin.getPageError()
137+
expect( pageError ).toBeNull()
114138
} )
115139
} )

e2e/tests/global-settings.spec.ts

Lines changed: 63 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { test, expect } from 'e2e/test-utils'
2-
import { createColor, getRgb } from '~stackable/plugins/global-settings/colors/util'
32

4-
test.describe( 'Global Settigs', () => {
3+
test.describe( 'Global Settings', () => {
54
let pid = null
65

76
// Create Posts for testing
@@ -22,6 +21,7 @@ test.describe( 'Global Settigs', () => {
2221
editor,
2322
} ) => {
2423
await page.getByLabel( 'Stackable Settings' ).click()
24+
await page.getByRole( 'button', { name: 'Global Color Palette' } ).click()
2525

2626
// Add a new Global Color
2727
const panel = page.locator( '.ugb-global-settings-color-picker ' ).filter( { hasText: 'Global Colors' } )
@@ -51,18 +51,31 @@ test.describe( 'Global Settigs', () => {
5151

5252
// Verify the newly added global color is in the color picker
5353
await expect( page.getByRole( 'heading', { name: 'Global Colors' } ) ).toBeVisible()
54-
await expect( page.getByLabel( `Color: Custom Color ${ count }` ) ).toBeVisible()
54+
55+
// For WP 6.7 and below, the label for colors has a prefix `Color: `
56+
// For WP 6.8 the prefix was removed.
57+
const regex = new RegExp( `^(?:Color:\\s*)?Custom Color ${ count }$` )
58+
59+
await expect( page.getByLabel( regex ) ).toBeVisible()
5560

5661
// Verify the color value
57-
await page.getByLabel( `Color: Custom Color ${ count }` ).click()
62+
await page.getByLabel( regex ).click()
5863
await expect( page.getByLabel( 'Hex color' ) ).toHaveValue( hexValue )
5964

6065
// Click on the color picker button to close the popup
6166
await page.locator( '.stk-color-palette-control .stk-control-content > .components-dropdown > .components-button' ).first().click()
6267

6368
// Delete added Global Color
6469
await page.getByLabel( 'Stackable Settings' ).click()
65-
await panel.locator( `.ugb-global-settings-color-picker__color-indicators > div > div:nth-child(${ count }) > button.stk-global-settings-color-picker__delete-button` ).click()
70+
71+
page.on( 'dialog', async dialog => await dialog.accept() )
72+
const deleteRequest = page.waitForResponse( response => response.url().includes( 'wp/v2/settings' ) && response.request().method() === 'POST' )
73+
74+
await globalColors.getByLabel( 'Delete' ).nth( count - 1 ).click()
75+
76+
await deleteRequest
77+
const _count = ( await globalColors.evaluate( node => Array.from( node.childNodes ) ) ).length
78+
expect( _count ).toBeLessThan( count )
6679
} )
6780

6881
test( 'Global Typography Styles should be applied when adding a heading', async ( {
@@ -93,56 +106,81 @@ test.describe( 'Global Settigs', () => {
93106

94107
await expect( editor.canvas.locator( '[data-type="stackable/heading"] > .stk-block-heading > h2[role="textbox"]' ) ).toHaveCSS( 'font-size', '32px' )
95108

96-
// Reset Global Typography Styles
97-
await page.getByLabel( 'Stackable Settings' ).click()
98-
await page.locator( '.ugb-global-settings-typography-control' ).nth( 1 ).getByRole( 'button', { name: 'Reset' } ).click()
109+
// Reset Global Typography Styles
110+
await page.getByLabel( 'Stackable Settings' ).click()
111+
112+
const resetButton = page.locator( '.ugb-global-settings-typography-control' ).nth( 1 ).getByLabel( 'Reset' )
113+
const deleteRequest = page.waitForResponse( response => response.url().includes( 'wp/v2/settings' ) && response.request().method() === 'POST' )
114+
await resetButton.click()
115+
116+
await deleteRequest
117+
await expect( resetButton ).not.toBeVisible()
99118
} )
100119

101120
test( 'When a default block is created, adding the block should have the default block\'s attributes', async ( {
102121
page,
103122
editor,
104123
} ) => {
105-
// Generate a color
106-
const color = createColor()
107-
108124
await page.getByLabel( 'Stackable Settings' ).click()
109125
await page.getByRole( 'button', { name: 'Block Defaults' } ).click()
110126

111127
// Open the Default Text Block Editor
112128
const defaultBlockPagePromise = page.waitForEvent( 'popup' )
129+
130+
// Reset the block defaults first if it has been edited
131+
const resetButton = page.locator( '.components-panel__body', { hasText: 'Block Defaults' } ).locator( '.stk-block-default-control', { hasText: /^Text$/ } ).first().getByLabel( 'Reset' )
132+
133+
if ( await resetButton.isVisible() ) {
134+
await resetButton.click()
135+
}
136+
113137
const textBlock = page.locator( '.components-panel__body', { hasText: 'Block Defaults' } ).locator( '.stk-block-default-control', { hasText: /^Text$/ } ).first().getByLabel( 'Edit' )
114138
await textBlock.click()
115139
const defaultBlockPage = await defaultBlockPagePromise
116140

117141
// Set a color for the default Text Block
118142
await defaultBlockPage.locator( '.stk-color-palette-control .stk-control-content > .components-dropdown > .components-button' ).first().click()
119-
await defaultBlockPage.getByLabel( 'Hex color' ).fill( color )
143+
await defaultBlockPage.getByLabel( 'Hex color' ).fill( 'ff0000' )
120144
await defaultBlockPage.locator( '.stk-color-palette-control .stk-control-content > .components-dropdown > .components-button' ).first().click()
121145

146+
// The default timeout is 30s, extend it to 90s
147+
const updateRequest = defaultBlockPage.waitForResponse( response => response.url().includes( 'update_block_style' ) && response.request().method() === 'POST', { timeout: 90_000 } )
148+
122149
// In older WP versions, the button text is 'Update' instead of 'Save'
123-
if ( await defaultBlockPage.getByRole( 'button', { name: 'Save', exact: true } ).isVisible() ) {
150+
if ( await defaultBlockPage.getByRole( 'button', {
151+
name: 'Save', exact: true, disabled: false,
152+
} ).isVisible() ) {
124153
await defaultBlockPage.getByRole( 'button', { name: 'Save', exact: true } ).click()
125-
} else {
154+
} else if ( await defaultBlockPage.getByRole( 'button', { name: 'Update', disabled: false } ).isVisible() ) {
126155
await defaultBlockPage.getByRole( 'button', { name: 'Update' } ).click()
127156
}
128157

129-
await defaultBlockPage.close()
158+
// Make sure default block has been updated
159+
await ( await updateRequest ).finished()
130160

131161
// Insert a Stackable Text Block, and check if the color is the same as the one set in the default block
132-
await page.reload()
133-
await editor.insertBlock( {
134-
name: 'stackable/text',
135-
attributes: {
136-
text: 'test',
137-
},
138-
} )
139-
140-
await expect( editor.canvas.locator( '[data-type="stackable/text"] > .stk-block-text > p[role="textbox"]' ) ).toHaveCSS( 'color', `rgb(${ getRgb( color ) })` )
162+
const timeouts = [ 1_000, 5_000, 30_000 ]
163+
for ( const timeout of timeouts ) {
164+
try {
165+
await page.reload()
166+
await editor.insertBlock( {
167+
name: 'stackable/text',
168+
attributes: {
169+
text: 'test',
170+
},
171+
} )
172+
173+
await expect( editor.canvas.locator( '[data-type="stackable/text"] > .stk-block-text > p[role="textbox"]' ) ).toHaveCSS( 'color', 'rgb(255, 0, 0)' )
174+
break
175+
} catch ( e ) {
176+
// Ignore the error and try again because the default block might not be updated yet
177+
await page.waitForTimeout( timeout )
178+
}
179+
}
141180

142181
// Reset Default Block
143182
await page.getByLabel( 'Stackable Settings' ).click()
144183
await page.getByRole( 'button', { name: 'Block Defaults' } ).click()
145184
await page.locator( '.components-panel__body', { hasText: 'Block Defaults' } ).locator( '.stk-block-default-control', { hasText: /^Text$/ } ).first().getByLabel( 'Reset' ).click()
146185
} )
147186
} )
148-

0 commit comments

Comments
 (0)