primefaces / primereact

The Most Complete React UI Component Library
https://primereact.org
MIT License
6.62k stars 1k forks source link

Could not parse CSS @layer during jest test after upgrading to 10.0.5 #5156

Closed FAMSTM closed 10 months ago

FAMSTM commented 10 months ago

Describe the bug

I'm getting this error after upgrading from 9.6.2 to 10.0.5 during a jest testing-library test run on datatable component (jsdom cannot parse @layer in CSS):

  console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
    Error: Could not parse CSS stylesheet
        at exports.createStylesheet (/project/home/famstm/workspace/node_modules/jsdom/lib/jsdom/living/helpers/stylesheets.js:35:21)
        at HTMLStyleElementImpl._updateAStyleBlock (/project/home/famstm/workspace/node_modules/jsdom/lib/jsdom/living/nodes/HTMLStyleElement-impl.js:67:5)
        at HTMLStyleElementImpl._childTextContentChangeSteps (/project/home/famstm/workspace/node_modules/jsdom/lib/jsdom/living/nodes/HTMLStyleElement-impl.js:36:12)
        at HTMLStyleElementImpl.insertBefore (/project/home/famstm/workspace/node_modules/jsdom/lib/jsdom/living/nodes/Node-impl.js:214:14)
        at HTMLStyleElementImpl.appendChild (/project/home/famstm/workspace/node_modules/jsdom/lib/jsdom/living/nodes/Node-impl.js:316:17)
        at HTMLStyleElementImpl.set textContent [as textContent] (/project/home/famstm/workspace/node_modules/jsdom/lib/jsdom/living/nodes/Node-impl.js:537:16)
        at HTMLStyleElement.set [as textContent] (/project/home/famstm/workspace/node_modules/jsdom/lib/jsdom/living/generated/Node.js:536:31)
        at load (/project/home/famstm/workspace/node_modules/primereact/hooks/hooks.cjs.js:1009:34)
        at /project/home/famstm/workspace/node_modules/primereact/componentbase/componentbase.cjs.js:328:7
        at commitHookEffectList (/project/home/famstm/workspace/node_modules/react-dom/cjs/react-dom.development.js:22030:26) 
    @layer primereact {
        .p-component, .p-component * {
            box-sizing: border-box;
        }

        .p-hidden {
            display: none;
        }

        .p-hidden-space {
            visibility: hidden;
        }

        .p-reset {
            margin: 0;
            padding: 0;
            border: 0;
            outline: 0;
            text-decoration: none;
            font-size: 100%;
            list-style: none;
        }

        .p-disabled, .p-disabled * {
            cursor: default !important;
            pointer-events: none;
            user-select: none;
        }

        .p-component-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
        }

        .p-unselectable-text {
            user-select: none;
        }

        .p-scrollbar-measure {
            width: 100px;
            height: 100px;
            overflow: scroll;
            position: absolute;
            top: -9999px;
        }

        @-webkit-keyframes p-fadein {
          0%   { opacity: 0; }
          100% { opacity: 1; }
        }
        @keyframes p-fadein {
          0%   { opacity: 0; }
          100% { opacity: 1; }
        }

        .p-link {
            text-align: left;
            background-color: transparent;
            margin: 0;
            padding: 0;
            border: none;
            cursor: pointer;
            user-select: none;
        }

        .p-link:disabled {
            cursor: default;
        }

        /* Non react overlay animations */
        .p-connected-overlay {
            opacity: 0;
            transform: scaleY(0.8);
            transition: transform .12s cubic-bezier(0, 0, 0.2, 1), opacity .12s cubic-bezier(0, 0, 0.2, 1);
        }

        .p-connected-overlay-visible {
            opacity: 1;
            transform: scaleY(1);
        }

        .p-connected-overlay-hidden {
            opacity: 0;
            transform: scaleY(1);
            transition: opacity .1s linear;
        }

        /* React based overlay animations */
        .p-connected-overlay-enter {
            opacity: 0;
            transform: scaleY(0.8);
        }

        .p-connected-overlay-enter-active {
            opacity: 1;
            transform: scaleY(1);
            transition: transform .12s cubic-bezier(0, 0, 0.2, 1), opacity .12s cubic-bezier(0, 0, 0.2, 1);
        }

        .p-connected-overlay-enter-done {
            transform: none;
        }

        .p-connected-overlay-exit {
            opacity: 1;
        }

        .p-connected-overlay-exit-active {
            opacity: 0;
            transition: opacity .1s linear;
        }

        /* Toggleable Content */
        .p-toggleable-content-enter {
            max-height: 0;
        }

        .p-toggleable-content-enter-active {
            overflow: hidden;
            max-height: 1000px;
            transition: max-height 1s ease-in-out;
        }

        .p-toggleable-content-enter-done {
            transform: none;
        }

        .p-toggleable-content-exit {
            max-height: 1000px;
        }

        .p-toggleable-content-exit-active {
            overflow: hidden;
            max-height: 0;
            transition: max-height 0.45s cubic-bezier(0, 1, 0, 1);
        }

        .p-sr-only {
            border: 0;
            clip: rect(1px, 1px, 1px, 1px);
            clip-path: inset(50%);
            height: 1px;
            margin: -1px;
            overflow: hidden;
            padding: 0;
            position: absolute;
            width: 1px;
            word-wrap: normal !important;
        }

        /* @todo Refactor */
        .p-menu .p-menuitem-link {
            cursor: pointer;
            display: flex;
            align-items: center;
            text-decoration: none;
            overflow: hidden;
            position: relative;
        }

    .p-button {
        margin: 0;
        display: inline-flex;
        cursor: pointer;
        user-select: none;
        align-items: center;
        vertical-align: bottom;
        text-align: center;
        overflow: hidden;
        position: relative;
    }

    .p-button-label {
        flex: 1 1 auto;
    }

    .p-button-icon-right {
        order: 1;
    }

    .p-button:disabled {
        cursor: default;
    }

    .p-button-icon-only {
        justify-content: center;
    }

    .p-button-icon-only .p-button-label {
        visibility: hidden;
        width: 0;
        flex: 0 0 auto;
    }

    .p-button-vertical {
        flex-direction: column;
    }

    .p-button-icon-bottom {
        order: 2;
    }

    .p-buttonset .p-button {
        margin: 0;
    }

    .p-buttonset .p-button:not(:last-child) {
        border-right: 0 none;
    }

    .p-buttonset .p-button:not(:first-of-type):not(:last-of-type) {
        border-radius: 0;
    }

    .p-buttonset .p-button:first-of-type {
        border-top-right-radius: 0;
        border-bottom-right-radius: 0;
    }

    .p-buttonset .p-button:last-of-type {
        border-top-left-radius: 0;
        border-bottom-left-radius: 0;
    }

    .p-buttonset .p-button:focus {
        position: relative;
        z-index: 1;
    }

    .p-checkbox {
        display: inline-flex;
        cursor: pointer;
        user-select: none;
        vertical-align: bottom;
        position: relative;
    }

    .p-checkbox.p-checkbox-disabled {
        cursor: auto;
    }

    .p-checkbox-box {
        display: flex;
        justify-content: center;
        align-items: center;
    }

    .p-inputtext {
        margin: 0;
    }

    .p-fluid .p-inputtext {
        width: 100%;
    }

    /* InputGroup */
    .p-inputgroup {
        display: flex;
        align-items: stretch;
        width: 100%;
    }

    .p-inputgroup-addon {
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .p-inputgroup .p-float-label {
        display: flex;
        align-items: stretch;
        width: 100%;
    }

    .p-inputgroup .p-inputtext,
    .p-fluid .p-inputgroup .p-inputtext,
    .p-inputgroup .p-inputwrapper,
    .p-fluid .p-inputgroup .p-input {
        flex: 1 1 auto;
        width: 1%;
    }

    /* Floating Label */
    .p-float-label {
        display: block;
        position: relative;
    }

    .p-float-label label {
        position: absolute;
        pointer-events: none;
        top: 50%;
        margin-top: -0.5rem;
        transition-property: all;
        transition-timing-function: ease;
        line-height: 1;
    }

    .p-float-label textarea ~ label,
    .p-float-label .p-mention ~ label {
        top: 1rem;
    }

    .p-float-label input:focus ~ label,
    .p-float-label input:-webkit-autofill ~ label,
    .p-float-label input.p-filled ~ label,
    .p-float-label textarea:focus ~ label,
    .p-float-label textarea.p-filled ~ label,
    .p-float-label .p-inputwrapper-focus ~ label,
    .p-float-label .p-inputwrapper-filled ~ label,
    .p-float-label .p-tooltip-target-wrapper ~ label {
        top: -0.75rem;
        font-size: 12px;
    }

    .p-float-label .p-placeholder,
    .p-float-label input::placeholder,
    .p-float-label .p-inputtext::placeholder {
        opacity: 0;
        transition-property: all;
        transition-timing-function: ease;
    }

    .p-float-label .p-focus .p-placeholder,
    .p-float-label input:focus::placeholder,
    .p-float-label .p-inputtext:focus::placeholder {
        opacity: 1;
        transition-property: all;
        transition-timing-function: ease;
    }

    .p-input-icon-left,
    .p-input-icon-right {
        position: relative;
        display: inline-block;
    }

    .p-input-icon-left > i,
    .p-input-icon-right > i,
    .p-input-icon-left > svg,
    .p-input-icon-right > svg,
    .p-input-icon-left > .p-input-prefix,
    .p-input-icon-right > .p-input-suffix {
        position: absolute;
        top: 50%;
        margin-top: -0.5rem;
    }

    .p-fluid .p-input-icon-left,
    .p-fluid .p-input-icon-right {
        display: block;
        width: 100%;
    }

    .p-radiobutton {
        display: inline-flex;
        cursor: pointer;
        user-select: none;
        vertical-align: bottom;
    }

    .p-radiobutton-box {
        display: flex;
        justify-content: center;
        align-items: center;
    }

    .p-radiobutton-icon {
        -webkit-backface-visibility: hidden;
        backface-visibility: hidden;
        transform: translateZ(0) scale(.1);
        border-radius: 50%;
        visibility: hidden;
    }

    .p-radiobutton-box.p-highlight .p-radiobutton-icon {
        transform: translateZ(0) scale(1.0, 1.0);
        visibility: visible;
    }

    .p-icon {
        display: inline-block;
    }

    .p-icon-spin {
        -webkit-animation: p-icon-spin 2s infinite linear;
        animation: p-icon-spin 2s infinite linear;
    }

    svg.p-icon {
        pointer-events: auto;
    }

    svg.p-icon g {
        pointer-events: none;
    }

    @-webkit-keyframes p-icon-spin {
        0% {
            -webkit-transform: rotate(0deg);
            transform: rotate(0deg);
        }
        100% {
            -webkit-transform: rotate(359deg);
            transform: rotate(359deg);
        }
    }

    @keyframes p-icon-spin {
        0% {
            -webkit-transform: rotate(0deg);
            transform: rotate(0deg);
        }
        100% {
            -webkit-transform: rotate(359deg);
            transform: rotate(359deg);
        }
    }

    }

  console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
    Error: Could not parse CSS stylesheet
        at exports.createStylesheet (/project/home/famstm/workspace/node_modules/jsdom/lib/jsdom/living/helpers/stylesheets.js:35:21)
        at HTMLStyleElementImpl._updateAStyleBlock (/project/home/famstm/workspace/node_modules/jsdom/lib/jsdom/living/nodes/HTMLStyleElement-impl.js:67:5)
        at HTMLStyleElementImpl._childTextContentChangeSteps (/project/home/famstm/workspace/node_modules/jsdom/lib/jsdom/living/nodes/HTMLStyleElement-impl.js:36:12)
        at HTMLStyleElementImpl.insertBefore (/project/home/famstm/workspace/node_modules/jsdom/lib/jsdom/living/nodes/Node-impl.js:214:14)
        at HTMLStyleElementImpl.appendChild (/project/home/famstm/workspace/node_modules/jsdom/lib/jsdom/living/nodes/Node-impl.js:316:17)
        at HTMLStyleElementImpl.set textContent [as textContent] (/project/home/famstm/workspace/node_modules/jsdom/lib/jsdom/living/nodes/Node-impl.js:537:16)
        at HTMLStyleElement.set [as textContent] (/project/home/famstm/workspace/node_modules/jsdom/lib/jsdom/living/generated/Node.js:536:31)
        at load (/project/home/famstm/workspace/node_modules/primereact/hooks/hooks.cjs.js:1009:34)
        at /project/home/famstm/workspace/node_modules/primereact/componentbase/componentbase.cjs.js:329:18
        at commitHookEffectList (/project/home/famstm/workspace/node_modules/react-dom/cjs/react-dom.development.js:22030:26) 
    @layer primereact {
        .p-datatable {
            position: relative;
        }

        .p-datatable > .p-datatable-wrapper {
            overflow: auto;
        }

        .p-datatable-table {
            border-spacing: 0px;
            width: 100%;
        }

        .p-datatable .p-sortable-disabled {
            cursor: auto;
        }

        .p-datatable .p-sortable-column {
            cursor: pointer;
            user-select: none;
        }

        .p-datatable .p-sortable-column .p-column-title,
        .p-datatable .p-sortable-column .p-sortable-column-icon,
        .p-datatable .p-sortable-column .p-sortable-column-badge {
            vertical-align: middle;
        }

        .p-datatable .p-sortable-column .p-sortable-column-badge {
            display: inline-flex;
            align-items: center;
            justify-content: center;
        }

        .p-datatable-selectable .p-selectable-row,
        .p-datatable-selectable-cell .p-selectable-cell {
            cursor: pointer;
        }

        .p-datatable-drag-selection-helper {
            position: absolute;
            z-index: 99999999;
        }

        /* Scrollable */
        .p-datatable-scrollable > .p-datatable-wrapper {
            position: relative;
        }

        .p-datatable-scrollable-table > .p-datatable-thead {
            position: sticky;
            top: 0;
            z-index: 1;
        }

        .p-datatable-scrollable-table > .p-datatable-frozen-tbody {
            position: sticky;
            z-index: 1;
        }

        .p-datatable-scrollable-table > .p-datatable-tfoot {
            position: sticky;
            bottom: 0;
            z-index: 1;
        }

        .p-datatable-scrollable .p-frozen-column {
            position: sticky;
            background: inherit;
        }

        .p-datatable-scrollable th.p-frozen-column {
            z-index: 1;
        }

        .p-datatable-flex-scrollable {
            display: flex;
            flex-direction: column;
            height: 100%;
        }

        .p-datatable-flex-scrollable > .p-datatable-wrapper {
            display: flex;
            flex-direction: column;
            flex: 1;
            height: 100%;
        }

        .p-datatable-scrollable-table > .p-datatable-tbody > .p-rowgroup-header {
            position: sticky;
            z-index: 1;
        }

        /* Resizable */
        .p-datatable-resizable-table > .p-datatable-thead > tr > th,
        .p-datatable-resizable-table > .p-datatable-tfoot > tr > td,
        .p-datatable-resizable-table > .p-datatable-tbody > tr > td {
            overflow: hidden;
            white-space: nowrap;
        }

        .p-datatable-resizable-table > .p-datatable-thead > tr > th.p-resizable-column:not(.p-frozen-column) {
            background-clip: padding-box;
            position: relative;
        }

        .p-datatable-resizable-table-fit > .p-datatable-thead > tr > th.p-resizable-column:last-child .p-column-resizer {
            display: none;
        }

        .p-datatable .p-column-resizer {
            display: block;
            position: absolute !important;
            top: 0;
            right: 0;
            margin: 0;
            width: 0.5rem;
            height: 100%;
            padding: 0px;
            cursor: col-resize;
            border: 1px solid transparent;
        }

        .p-datatable .p-column-header-content {
            display: flex;
            align-items: center;
        }

        .p-datatable .p-column-resizer-helper {
            width: 1px;
            position: absolute;
            z-index: 10;
            display: none;
        }

        .p-datatable .p-row-editor-init,
        .p-datatable .p-row-editor-save,
        .p-datatable .p-row-editor-cancel {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            overflow: hidden;
            position: relative;
        }

        /* Expand */
        .p-datatable .p-row-toggler {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            overflow: hidden;
            position: relative;
        }

        /* Reorder */
        .p-datatable-reorder-indicator-up,
        .p-datatable-reorder-indicator-down {
            position: absolute;
            display: none;
        }

        .p-reorderable-column,
        .p-datatable-reorderablerow-handle {
            cursor: move;
        }

        /* Loader */
        .p-datatable .p-datatable-loading-overlay {
            position: absolute;
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 2;
        }

        /* Filter */
        .p-column-filter-row {
            display: flex;
            align-items: center;
            width: 100%;
        }

        .p-column-filter-menu {
            display: inline-flex;
            margin-left: auto;
        }

        .p-column-filter-row .p-column-filter-element {
            flex: 1 1 auto;
            width: 1%;
        }

        .p-column-filter-menu-button,
        .p-column-filter-clear-button {
            display: inline-flex;
            justify-content: center;
            align-items: center;
            cursor: pointer;
            text-decoration: none;
            overflow: hidden;
            position: relative;
        }

        .p-column-filter-overlay {
            position: absolute;
            top: 0;
            left: 0;
        }

        .p-column-filter-row-items {
            margin: 0;
            padding: 0;
            list-style: none;
        }

        .p-column-filter-row-item {
            cursor: pointer;
        }

        .p-column-filter-add-button,
        .p-column-filter-remove-button {
            justify-content: center;
        }

        .p-column-filter-add-button .p-button-label,
        .p-column-filter-remove-button .p-button-label {
            flex-grow: 0;
        }

        .p-column-filter-buttonbar {
            display: flex;
            align-items: center;
            justify-content: space-between;
        }

        .p-column-filter-buttonbar .p-button:not(.p-button-icon-only) {
            width: auto;
        }

        /* Responsive */
        .p-datatable .p-datatable-tbody > tr > td > .p-column-title {
            display: none;
        }

        /* VirtualScroller */
        .p-datatable-virtualscroller-spacer {
            display: flex;
        }

        .p-datatable .p-virtualscroller .p-virtualscroller-loading {
            transform: none !important;
            min-height: 0;
            position: sticky;
            top: 0;
            left: 0;
        }

        /* Alignment */
        .p-datatable .p-datatable-thead > tr > th.p-align-left > .p-column-header-content,
        .p-datatable .p-datatable-tbody > tr > td.p-align-left,
        .p-datatable .p-datatable-tfoot > tr > td.p-align-left {
            text-align: left;
            justify-content: flex-start;
        }

        .p-datatable .p-datatable-thead > tr > th.p-align-right > .p-column-header-content,
        .p-datatable .p-datatable-tbody > tr > td.p-align-right,
        .p-datatable .p-datatable-tfoot > tr > td.p-align-right {
            text-align: right;
            justify-content: flex-end;
        }

        .p-datatable .p-datatable-thead > tr > th.p-align-center > .p-column-header-content,
        .p-datatable .p-datatable-tbody > tr > td.p-align-center,
        .p-datatable .p-datatable-tfoot > tr > td.p-align-center {
            text-align: center;
            justify-content: center;
        }
    }

Reproducer

https://codesandbox.io/p/sandbox/testing-with-jest-forked-lpzj27

PrimeReact version

10.0.5

React version

17.x

Language

TypeScript

Build / Runtime

Create React App (CRA)

Browser(s)

Chrome 118

Steps to reproduce the behavior

  1. Open the codesanbox link https://codesandbox.io/p/sandbox/testing-with-jest-forked-lpzj27
  2. Open a terminal
  3. Launch yarn test

=> the error will be displayed

Expected behavior

No error

melloware commented 10 months ago

@FAMSTM its a JSDOM issues with Layers we fixed it like this..

https://github.com/primefaces/primereact/pull/5092

Not great but nothing else you can do its a core JSDOM issue.

FlipWarthog commented 10 months ago

There's an alternative solution that @mertsincan posted in this PrimeVue issue. I couldn't apply it on the React side but you might have better luck.

FAMSTM commented 10 months ago

Thank you, I used this method https://github.com/primefaces/primevue/issues/4512#issuecomment-1749633215

melloware commented 10 months ago

@FAMSTM Oh we tried to use the same thing here on PrimeReact and it didn't work. Can you post what you did for React?