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
3 changes: 3 additions & 0 deletions .wp-env.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"."
],
"themes": [],
"mappings": {
"wp-content/mu-plugins/visualizer-e2e-enable-database-source.php": "./tests/e2e/config/enable-database-source.php"
},
"config": {
"WP_DEBUG": true,
"WP_DEBUG_LOG": true,
Expand Down
28 changes: 28 additions & 0 deletions js/frame.js
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,34 @@

init_db_import_component();

var settings_button = document.querySelector( '#settings-button' );
if ( settings_button ) {
settings_button.addEventListener( 'click', function( event ){
$('body').trigger('visualizer:db:query:update', {});
if( $( '#db-chart-button' ).attr( 'data-current' ) !== 'filter' || $( '.visualizer-db-query' ).val().length === 0 ){
return;
}

event.preventDefault();
event.stopImmediatePropagation();

var query_saved = false;
var resume_save = function(){
query_saved = true;
settings_button.click();
};

$('body').one( 'visualizer:render:currentchart:update', resume_save );
$( '#thehole' ).one( 'load', function(){
$('body').off( 'visualizer:render:currentchart:update', resume_save );
if ( ! query_saved ) {
$( '#db-chart-button' ).trigger( 'click' );
}
} );
$( '#db-chart-button' ).trigger( 'click' );
}, true );
}

$('#visualizer-query-fetch').on('click', function(e){

$('body').trigger('visualizer:db:query:update', {});
Expand Down
26 changes: 26 additions & 0 deletions tests/e2e/config/enable-database-source.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php
/**
* Enable database-source E2E tests for requests carrying the test cookie.
*/

if ( defined( 'TI_E2E_TESTING' ) && isset( $_COOKIE['visualizer_e2e_database_source'] ) ) {
defined( 'VISUALIZER_PRO_VERSION' ) || define( 'VISUALIZER_PRO_VERSION', '2.0.1' );

if ( ! class_exists( 'Visualizer_Pro' ) ) {
class Visualizer_Pro {
const ACTION_FETCH_DATA = 'visualizer-fetch-data';
const CF_PERMISSIONS = 'visualizer-permissions';
}
}

add_filter( 'visualizer_is_pro', '__return_true', PHP_INT_MAX );

add_filter(
'visualizer_pro_upsell_class',
function ( $class, $feature = '' ) {
return 'db-query' === $feature ? '' : $class;
},
PHP_INT_MAX,
2
);
}
211 changes: 211 additions & 0 deletions tests/e2e/specs/database-source.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/**
* WordPress dependencies
*/
const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' );

/**
* Internal dependencies
*/
const {
CHART_JS_LABELS,
deleteAllCharts,
selectChartAdmin,
} = require( '../utils/common' );

async function setQuery( chartEditor, query ) {
await chartEditor
.locator( '#visualizer-db-query .CodeMirror' )
.evaluate(
( editor, sql ) => editor.CodeMirror.setValue( sql ),
query
);
}

async function showQueryResults( page, chartEditor, expectedValue ) {
const [ response ] = await Promise.all( [
page.waitForResponse( ( candidate ) => {

Check failure on line 26 in tests/e2e/specs/database-source.spec.js

View workflow job for this annotation

GitHub Actions / Playwright E2E tests

[chromium] › tests/e2e/specs/database-source.spec.js:68:2 › Database source › saves previewed one-time data when saving the chart

1) [chromium] › tests/e2e/specs/database-source.spec.js:68:2 › Database source › saves previewed one-time data when saving the chart Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── TimeoutError: page.waitForResponse: Timeout 20000ms exceeded while waiting for event "response" 24 | async function showQueryResults( page, chartEditor, expectedValue ) { 25 | const [ response ] = await Promise.all( [ > 26 | page.waitForResponse( ( candidate ) => { | ^ 27 | const request = candidate.request(); 28 | 29 | return ( at showQueryResults (/home/runner/work/visualizer/visualizer/tests/e2e/specs/database-source.spec.js:26:8) at /home/runner/work/visualizer/visualizer/tests/e2e/specs/database-source.spec.js:174:9

Check failure on line 26 in tests/e2e/specs/database-source.spec.js

View workflow job for this annotation

GitHub Actions / Playwright E2E tests

[chromium] › tests/e2e/specs/database-source.spec.js:68:2 › Database source › saves previewed one-time data when saving the chart

1) [chromium] › tests/e2e/specs/database-source.spec.js:68:2 › Database source › saves previewed one-time data when saving the chart TimeoutError: page.waitForResponse: Timeout 20000ms exceeded while waiting for event "response" 24 | async function showQueryResults( page, chartEditor, expectedValue ) { 25 | const [ response ] = await Promise.all( [ > 26 | page.waitForResponse( ( candidate ) => { | ^ 27 | const request = candidate.request(); 28 | 29 | return ( at showQueryResults (/home/runner/work/visualizer/visualizer/tests/e2e/specs/database-source.spec.js:26:8) at /home/runner/work/visualizer/visualizer/tests/e2e/specs/database-source.spec.js:174:9
const request = candidate.request();

return (
candidate.url().includes( '/wp-admin/admin-ajax.php' ) &&
request.method() === 'POST' &&
request
.postData()
?.includes( 'action=visualizer-fetch-db-data' )
);
} ),
chartEditor.getByRole( 'button', { name: 'Show Results' } ).click(),
] );

expect( response.ok() ).toBe( true );
await expect( chartEditor.locator( '.db-wizard-results' ) ).toContainText(
expectedValue
);
}

test.describe( 'Database source', () => {
const postIds = [];

test.beforeEach( async ( { page, requestUtils } ) => {
await deleteAllCharts( requestUtils );
page.setDefaultTimeout( 20000 );
} );

test.afterEach( async ( { requestUtils } ) => {
await Promise.all(
postIds.splice( 0 ).map( ( postId ) =>
requestUtils
.rest( {
method: 'DELETE',
path: `/wp/v2/posts/${ postId }`,
params: { force: true },
} )
.catch( () => {} )
)
);
} );

test( 'saves previewed one-time data when saving the chart', async ( {
admin,
context,
page,
requestUtils,
} ) => {
test.setTimeout( 180000 );

await page.goto( '/' );
await context.addCookies( [
{
name: 'visualizer_e2e_database_source',
value: '1',
url: page.url(),
},
] );

const sourcePost = await requestUtils.createPost( {
title: 'ISSUE_1329_OLD',
status: 'publish',
} );
postIds.push( sourcePost.id );

await admin.visitAdminPage(
'admin.php?page=visualizer&vaction=addnew'
);
await page
.getByRole( 'button', { name: 'Classic Builder Step-by-step' } )
.click();

const chartEditor = page.frameLocator( 'iframe' );
await chartEditor
.locator( 'div#type-picker' )
.waitFor( { state: 'visible', timeout: 20000 } );
await selectChartAdmin( chartEditor, CHART_JS_LABELS.table );

await chartEditor
.locator( '#visualizer-chart-id' )
.waitFor( { state: 'attached', timeout: 20000 } );
const chartId = await chartEditor
.locator( '#visualizer-chart-id' )
.getAttribute( 'data-id' );
expect( chartId ).toMatch( /^\d+$/ );

await chartEditor
.getByRole( 'button', { name: /Import from database/ } )
.click();
await chartEditor
.locator( '#db-chart-button' )
.evaluate( ( button ) => button.click() );

const query = `SELECT post_title AS value FROM wp_posts WHERE ID = ${ sourcePost.id }`;
await setQuery( chartEditor, query );

await showQueryResults( page, chartEditor, 'ISSUE_1329_OLD' );

const [ saveResponse ] = await Promise.all( [
page.waitForResponse(
( candidate ) =>
candidate
.url()
.includes( 'action=visualizer-save-db-query' ) &&
candidate.request().method() === 'POST'
),
chartEditor
.locator( '#db-chart-button' )
.evaluate( ( button ) => button.click() ),
] );
expect( saveResponse.ok() ).toBe( true );
await expect( chartEditor.locator( '#canvas' ) ).toContainText(
'ISSUE_1329_OLD',
{ timeout: 20000 }
);
await chartEditor
.getByRole( 'button', { name: 'Create Chart' } )
.click();
await expect(
page.getByRole( 'heading', { name: 'Visualizer Library' } )
).toBeVisible( { timeout: 20000 } );

const chartPost = await requestUtils.createPost( {
title: 'Issue 1329 chart',
content: `[visualizer id="${ chartId }"]`,
status: 'publish',
} );
postIds.push( chartPost.id );

await page.goto( chartPost.link );
await page.mouse.wheel( 0, 500 );
await expect(
page.getByRole( 'cell', { name: 'ISSUE_1329_OLD' } )
).toBeVisible();

await requestUtils.rest( {
method: 'POST',
path: `/wp/v2/posts/${ sourcePost.id }`,
data: { title: 'ISSUE_1329_NEW' },
} );

await admin.visitAdminPage( 'admin.php?page=visualizer' );
await page
.locator( `.visualizer-chart-edit[data-chart="${ chartId }"]` )
.click();
await chartEditor
.locator( '#db-chart-button' )
.evaluate( ( button ) => button.click() );
await showQueryResults( page, chartEditor, 'ISSUE_1329_NEW' );

await chartEditor.getByRole( 'button', { name: 'Save Chart' } ).click();
await expect(
page.getByRole( 'dialog', { name: 'Visualizer' } )
).toHaveCount( 0, { timeout: 30000 } );

await page.goto( chartPost.link );
await page.mouse.wheel( 0, 500 );
await expect(
page.getByRole( 'cell', { name: 'ISSUE_1329_NEW' } )
).toBeVisible();

await admin.visitAdminPage( 'admin.php?page=visualizer' );
await page
.locator( `.visualizer-chart-edit[data-chart="${ chartId }"]` )
.click();
await chartEditor
.locator( '#db-chart-button' )
.evaluate( ( button ) => button.click() );
await setQuery(
chartEditor,
'SELECT visualizer_missing_column FROM wp_posts'
);

const errorDialogPromise = page.waitForEvent( 'dialog' );

Check failure on line 199 in tests/e2e/specs/database-source.spec.js

View workflow job for this annotation

GitHub Actions / Playwright E2E tests

[chromium] › tests/e2e/specs/database-source.spec.js:68:2 › Database source › saves previewed one-time data when saving the chart

1) [chromium] › tests/e2e/specs/database-source.spec.js:68:2 › Database source › saves previewed one-time data when saving the chart Retry #2 ─────────────────────────────────────────────────────────────────────────────────────── TimeoutError: page.waitForEvent: Timeout 20000ms exceeded while waiting for event "dialog" =========================== logs =========================== waiting for event "dialog" ============================================================ 197 | ); 198 | > 199 | const errorDialogPromise = page.waitForEvent( 'dialog' ); | ^ 200 | await chartEditor.getByRole( 'button', { name: 'Save Chart' } ).click(); 201 | const errorDialog = await errorDialogPromise; 202 | await errorDialog.dismiss(); at /home/runner/work/visualizer/visualizer/tests/e2e/specs/database-source.spec.js:199:35
await chartEditor.getByRole( 'button', { name: 'Save Chart' } ).click();
const errorDialog = await errorDialogPromise;
await errorDialog.dismiss();

await expect(
chartEditor.locator( '#visualizer-db-query' )
).toBeVisible();
await expect(
page.getByRole( 'dialog', { name: 'Visualizer' } )
).toBeVisible();
} );
} );
Loading