diff --git a/.github/workflows/qunit_tests-additional-renovation.yml b/.github/workflows/qunit_tests-additional-renovation.yml index 462f1cf93846..f37ad80582c6 100644 --- a/.github/workflows/qunit_tests-additional-renovation.yml +++ b/.github/workflows/qunit_tests-additional-renovation.yml @@ -66,7 +66,7 @@ jobs: - name: Zip artifacts working-directory: ./packages/devextreme run: | - 7z a -tzip -mx3 -mmt2 artifacts.zip artifacts ../devextreme-scss/scss/bundles testing/tests/Renovation/widgets.json + 7z a -tzip -mx3 -mmt2 artifacts.zip artifacts ../devextreme-scss/scss/bundles - name: Upload build artifacts uses: actions/upload-artifact@v4 diff --git a/.github/workflows/qunit_tests-renovation.yml b/.github/workflows/qunit_tests-renovation.yml index 103fc669abf4..932f153566ec 100644 --- a/.github/workflows/qunit_tests-renovation.yml +++ b/.github/workflows/qunit_tests-renovation.yml @@ -53,7 +53,7 @@ jobs: - name: Zip artifacts working-directory: ./packages/devextreme run: | - 7z a -tzip -mx3 -mmt2 artifacts.zip artifacts ../devextreme-scss/scss/bundles testing/tests/Renovation/widgets.json + 7z a -tzip -mx3 -mmt2 artifacts.zip artifacts ../devextreme-scss/scss/bundles - name: Upload build artifacts uses: actions/upload-artifact@v4 diff --git a/.github/workflows/testcafe_tests.yml b/.github/workflows/testcafe_tests.yml index 3b52bb902d7c..009fe2d5ad2c 100644 --- a/.github/workflows/testcafe_tests.yml +++ b/.github/workflows/testcafe_tests.yml @@ -154,7 +154,7 @@ jobs: { componentFolder: "filterBuilder", name: "filterBuilder - fluent", theme: 'fluent.blue.light' }, ] runs-on: devextreme-shr2 - timeout-minutes: 45 + timeout-minutes: 120 steps: - name: Set machine timezone diff --git a/packages/devextreme/testing/.gitignore b/packages/devextreme/testing/.gitignore index 432ab075d7da..55291e5368c5 100644 --- a/packages/devextreme/testing/.gitignore +++ b/packages/devextreme/testing/.gitignore @@ -1,3 +1,2 @@ /Results.xml /js/renovation/code_coverage -/tests/Renovation/widgets.json diff --git a/packages/devextreme/testing/tests/Renovation/compatibility.test.js b/packages/devextreme/testing/tests/Renovation/compatibility.test.js deleted file mode 100644 index b8ac1ad623d5..000000000000 --- a/packages/devextreme/testing/tests/Renovation/compatibility.test.js +++ /dev/null @@ -1,174 +0,0 @@ -import $ from 'jquery'; -import widgetsMeta from './widgets.json!'; -import publicWidgets from 'renovation/components'; -import Button from 'ui/button'; -import 'ui/check_box'; -import 'ui/pager'; -import 'ui/data_grid'; - -/** - * List of registered jQuery widgets which were created only to be used from old DevExtreme code - */ -const PRIVATE_JQUERY_WIDGETS = [ - 'Widget', 'ResizableContainer', - 'TimePanelTableLayout', 'GroupPanel', 'HeaderPanelLayout', 'TimelineHeaderPanelLayout', - 'DateTableLayoutBase', 'AllDayPanelLayout', 'AllDayPanelTitle', 'MonthDateTableLayout', - 'AppointmentLayout', - 'GridPager', 'Scrollable', 'DraggableContainer', 'Droppable', - 'Editor' -]; - -const CUSTOM_ROOT_WIDGET_CLASS = { - 'dxGridPager': 'datagrid-pager', - 'dxDataGrid': 'widget', -}; - -const widgetsInBundle = publicWidgets - .filter((item) => !item.inProgress) - .map(widget => widget.name); -const isRenovation = !!Button.IS_RENOVATED_WIDGET; - -const widgets = isRenovation ? widgetsMeta - .filter((meta) => { - return PRIVATE_JQUERY_WIDGETS.indexOf(meta.name) === -1 - && widgetsInBundle.indexOf(meta.name) !== -1; - }) : []; - -QUnit.module('Check components registration', () => { - widgets - .forEach((meta) => { - QUnit.test(`${`dx${meta.name}`} is in bundle`, function(assert) { - const message = 'You should add your widget to the bundle.' - + 'See "bundles/modules/parts/renovation"'; - - assert.notStrictEqual(widgetsInBundle.indexOf(meta.name), -1, message); - }); - }); -}); - -QUnit.module('Mandatory component setup', { - beforeEach() { - $('#qunit-fixture').html(` -
-
-
- `); - } -}, () => { - widgets.forEach((meta) => { - QUnit.test(`${`dx${meta.name}`} - check css class names`, function(assert) { - $('#component')[`dx${meta.name}`](); - - let message = 'You should always set `dx-widget` class to the root of your component'; - - if(meta.name !== 'ScrollView') { - assert.equal($('#component').get(0), $('.dx-widget').get(0), message); - } - - const className = CUSTOM_ROOT_WIDGET_CLASS[`dx${meta.name}`] || meta.name.toLowerCase(); - message = 'Use `dx-` followed by lowercase Component name as css class name'; - assert.equal($('#component').get(0), $(`.dx-${className}`).get(0), message); - }); - }); - - widgets.forEach((meta) => { - QUnit.test(`${`dx${meta.name}`} - merge own classes with className from restAttributes`, function(assert) { - const message = 'You should merge your cssClass with className from restAttributes\n' - + '\n' - + 'get className() { return \`${this.restAttributes.className} dx-my-component\` }'; // eslint-disable-line - - $('#component').addClass('custom-class'); - $('#component')[`dx${meta.name}`](); - const className = CUSTOM_ROOT_WIDGET_CLASS[`dx${meta.name}`] || meta.name.toLowerCase(); - assert.equal($('#component').get(0), $(`.custom-class.dx-${className}`).get(0), message); - }); - }); - - widgets.forEach((meta) => { - QUnit.test(`${`dx${meta.name}`} - pass style to component's root`, function(assert) { - const message = 'If you do not specify style in your component just spread restAttributes\n' - + '\n\n' - + 'If you specify some styles then merge it with restAttributes.style object\n' - + '\n' - + 'get styles() { return { ...this.restAttributes.style, display: "inline" }; }'; - - $('#component').css({ - width: '100px', height: '50px', display: 'inline-block', - }); - - $('#component')[`dx${meta.name}`](); - - assert.equal($('#component').css('width'), '100px', message); - assert.equal($('#component').css('height'), '50px', message); - assert.equal($('#component').css('display'), 'inline-block', message); - }); - }); - - widgets - .filter((m) => m.props.allProps.indexOf('width') !== -1 && m.props.allProps.indexOf('width') !== -1) - .forEach((meta) => { - QUnit.test(`${`dx${meta.name}`} - width/height options take priority over container size`, function(assert) { - const message = 'If your component has width/height props, they should overwrite width/height properties in restAttributes.style\n' - + '\n' - + 'get styles() {\n' - + ' return {\n' - + ' ...this.restAttributes.style,\n' - + ' width: this.props.width,\n' - + ' height: this.props.height,\n' - + ' };\n' - + '}'; - - $('#component').css({ - width: '100px', height: '50px', - }); - - $('#component')[`dx${meta.name}`]({ - width: '110px', - height: '55px', - }); - - assert.equal($('#component').css('width'), '110px', message); - assert.equal($('#component').css('height'), '55px', message); - }); - }); - - widgets - .filter((m) => m.props.template.length) - .forEach((meta) => { - QUnit.test(`${`dx${meta.name}`} - pass right props to template`, function(assert) { - const message = 'For templates that jQuery users set.\n' - + 'You should pass only `data` and `index` (if applicable) props\n' - + 'when rendering template.\n' - + '
\n' - + ' {viewModel.props.template &&\n' - + ' }\n' - + ' {!viewModel.props.template && \'default content\'}\n' - + '
\n\n' - + 'If for some reason you don\'t have data (if it is based on other props) - exclude your component from the test below\n' - + 'and add correspondig tests in your component\'s test suite.'; - const templatesToCheck = meta.props.template.filter(templateName => { - // skip template here if you don't want to test its compatibility - return templateName !== 'iconTemplate' && templateName !== 'noDataTemplate' && templateName !== 'loadPanelTemplate'; - }); - assert.expect(templatesToCheck.length * 3); - - const options = templatesToCheck.reduce((r, template) => ({ - ...r, - [template]: sinon.spy() - }), {}); - - $('#component')[`dx${meta.name}`](options); - - templatesToCheck.forEach((template) => { - const [data, index, element = index] = options[template].getCall(0).args; - - assert.ok($('#component').has(element).length > 0, message); - assert.equal(element === index || (typeof index === 'number'), true, message); - assert.equal(typeof data === 'object', true, message); - }); - }); - }); -});