Injecting style into a tested page - css

I have an issue with the div:
<div id="root-hammerhead-shadow-ui" contenteditable="false" class="root-hammerhead-shadow-ui"></div>
which is injected by testcafe into an iframe that I'd like to test.
The iframe contains an input field and some styles which make the hammerhead div cover the iframe and input completely (width/height set to 100%) so I'm unable to use typeText with it (expect visible passes correctly).
I can fix the issue during debugging by setting the width/height of the hammerhead div to defaults, can I somehow do the same thing in code?

You can use the ClientFunction API to manipulate DOM elements on a client. Please take a look at the following example:
import { Selector, ClientFunction } from 'testcafe';
fixture `New Fixture`
.page `https://example.com`;
test('New Test', async t => {
const changeHammerheadDiv = ClientFunction(() => {
const hammerHeadDiv = document.getElementById('root-hammerhead-shadow-ui');
hammerHeadDiv.style.width = '0';
hammerHeadDiv.style.height = '0';
});
await t.switchToIframe(Selector('iframe'));
await changeHammerheadDiv();
await t.typeText(Selector('body').find('input'), 'qwerty');
});

Related

change global css element

i've made this banner like screen that appears when my site is loaded, but here's the thing, i don't want no scrollbar while this opening animation it's happening, i only want to show the other components (the scrollbar and the whole site) once the gsap animation finishes, how could i proceed? thanks! (i tried to create a function to control those global elements, is it a way?)
So if I understand correctly you need the Banner to be displayed until the site is loaded. Maybe you are making some API calls or in general, you are planning to show the banner for let's say 3 sec and post that you want your actual components to be displayed.
You can try below approch:
export const APP = (): JSX.Element => {
const [isAnimationInProgress, SetAnimationState] = React.useState(true);
React.useEffect(() => {
// You can have your page load API calls done here
// Or wait for 'X' seconds
// Post that set the AnimationState to false to render actual components
setAnimationState(false);
})
return (
{
isAnimationInProgress && <Banner />
}
{
!isAnimationInProgress && <ActualComponent />
}
)
}
Regarding scrollbars, including overflow: hidden; in style for the banner should do the work if you are getting scrollbars for the Banner component.

How should I write Jest Test cases for styled component and spy on css to verify if the styles?

I have a component in React-redux, which has a PagedGrid component (basically a table which renders data row-wise).
<UsersContainer>
<Title>{t('users')}</Title>
<PagedGrid
data-auto-container="user:table"
pageData={user.data}
columns={this.column}
/>
</UsersContainer>
I have created a function for the custom styled component which applies css to the rows of the table inside PagedGrid
const UsersContainer = styled.div`
> table > tbody {
${props => customcss(props)};
}
`;
function customcss({ data = [] }) {
let styles = '';
if (data.length > 0) {
data.forEach((value, index) => {
if (value.mycondition) {
const rowStyle = `& > tr:nth-child(${index + 1}) {
background-color: ${LIGHT_BLUE}
}`;
}
});
}
return css` ${rowStyle} `;
}
Now I want to create a test case using jest to spy on the css of this table and check if the styles are getting applied or not. Can anyone help me on creating a test case for this.
Assuming that you use the #testing-library/react library, you could test your component's style by getting it directly from the html document, and see precisely what style is used for your specific element.
In your example, you can do something like below (assuming that the ${LIGHT_BLUE} value is blue):
import React from 'react';
import { render } from '#testing-library/react';
import UsersContainer from '../UsersContainer';
it('should have the background color set to blue', () => {
const { container, getAllByTestId } = render(
<UsersContainer />
);
// Replace <YOUR_CSS_SELECTOR> by your component's css selector (that can be found in the inspector panel)
let contentDiv = document.querySelector('<YOUR_CSS_SELECTOR>');
let style = window.getComputedStyle(contentDiv[0]);
expect(style.color).toBe('blue');
}
Here, to get the style of your element, I am using the element's CSS Selector. However, it could also work with the element's className, or id directly if it has one, respectively using the methods document.getElementByClassName('YOUR_DIV_CLASS_NAME'), document.getElementId('YOUR_DIV_ID') instead of document.querySelector('<YOUR_CSS_SELECTOR>'). Note that the given name here should be unique, either with the id technique, or the className.

Cypress testing pseudo CSS class :before

Is there a way in which I can test the content of the pseudo CSS class for :before on my element with Cypress?
I have seen links documenting:
Accessing nth-child pseudo element
Accessing the actual content pseudo class of a normal CSS class
But I have not found anything for CSS classes using the ::before pseudo class.
Imagine the code:
.myClass:before {
content: "foo-";
}
<div>
<span class="myClass">Bar</span>
</div>
How could one test that 'foo-' is present?
There's a way to assert on the CSS properties of pseudo-elements, although it's not as simple as just using a Cypress command.
Use cy.get() to get a reference to the element.
Read the Window object off of the element, and then invoke Window.getComputedStyle(), which can read the computed CSS of pseudo selectors.
Use getPropertyValue on the returned CSS declaration to read the value of the content property.
Assert on it.
Here's an example that works on the code posted in the OP:
cy.get('.myClass')
.then($els => {
// get Window reference from element
const win = $els[0].ownerDocument.defaultView
// use getComputedStyle to read the pseudo selector
const before = win.getComputedStyle($els[0], 'before')
// read the value of the `content` CSS property
const contentValue = before.getPropertyValue('content')
// the returned value will have double quotes around it, but this is correct
expect(contentValue).to.eq('"foo-"')
})
Based on Zach's answer I created a command that returns the pseudo-element property (without single quotes around).
function unquote(str) {
return str.replace(/(^")|("$)/g, '');
}
Cypress.Commands.add(
'before',
{
prevSubject: 'element',
},
(el, property) => {
const win = el[0].ownerDocument.defaultView;
const before = win.getComputedStyle(el[0], 'before');
return unquote(before.getPropertyValue(property));
},
);
You will use it like this
it('color is black', () => {
cy.get('button')
.before('color')
.should('eq', 'rgb(0,0,0)'); // Or .then()
});
Try asserting on the text of the parent:
cy.get('.myClass').parent().should('have.text', 'foo-bar')
If that doesn't work, you may have to use the textContent property:
cy.get('.myClass').parent(). should($el => expect ($el).to.contain('foo-bar')
)
This was my solution to get, convert and compare a hexadecimal's background-color with a rgb returned.
const RGBToHex = (rgbColor) => {
// it parse rgb(255, 13, 200) to #fa92D4
const [red, green, blue] = rgbColor.replace(/[a-z]|\(|\)|\s/g, '').split(',');
let r = parseInt(red, 10).toString(16);
let g = parseInt(green, 10).toString(16);
let b = parseInt(blue, 10).toString(16);
if (r.length === 1) r = `0${r}`;
if (g.length === 1) g = `0${g}`;
if (b.length === 1) b = `0${b}`;
return `#${r}${g}${b}`;
};
cy.get('.element').then(($el) => {
const win = $el[0].ownerDocument.defaultView;
const before = win.getComputedStyle($el[0], 'before');
const bgColor = before.getPropertyValue('background-color');
expect(RGBToHex(bgColor)).to.eq('#HEXA');
});

Add a class to the parent .wp-block element in gutenberg editor

When Gutenberg creates a class, it seems to be of the format
div.wp-block
div.editor-block-list__insertion-point
div.editor-block-list__block-edit
div.editor-block-contextual-toolbar
div
<your actual block html goes here>
I'd like to be able to add a class to that top div.wp-block element so I can properly style my block in the editor. The class is dynamically generated based on an attribute so I can't just use the block name class. Is there a clean way of doing this? I can hack it using javascript DOM, but it gets overwritten quickly enough.
https://wordpress.org/gutenberg/handbook/designers-developers/developers/filters/block-filters/#editor-blocklistblock
const { createHigherOrderComponent } = wp.compose
const withCustomClassName = createHigherOrderComponent((BlockListBlock) => {
return props => {
return <BlockListBlock { ...props } className={ 'my-custom-class' } />
}
}, 'withCustomClassName')
wp.hooks.addFilter('editor.BlockListBlock', 'my-plugin/with-custom-class-name', withCustomClassName)
You can add class in your block edit view by using className that is present in this.props, className will print class in following format wp-blocks-[block_name]
edit( { className } ) { // using destructing from JavaScript ES-6
return <div className={ className }></div>
}
Suggestion
Always try to look for manipulating DOM via React instead of manipulating DOM directly because React manages it's own state and issues can occur by manipulating DOM directly.

angular testbed, query by css, find the pseudo element

I am writhing Angular 2+ unit test with TestBed.
Scenario, I want to verify my component, that the color of a pseudo element.
component.ts
label::before {
right: 0;
background-color: red;
}
#Component({
selector: 'app-test',
template: `
<div><label>a label</label></div>
`,
styleUrls: ['./test.component.scss'],
})
export class TestComponent {
}
so when I write unit test, I want to verify the pseudo element background color
beforeEach(() => {
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should set background color', () => {
const ele = fixture.debugElement.query(By.css('label::before')).nativeElement; // error here
// not sure how to use by.css to locate on the pseudo element
expect(ele.backgroundColor).toBe('....');
});
I would suggest writing your test in a different manner.
Fixture is of type ComponentFixture<T> where T is the component you are trying to access. The debugElement property has two properties that you are normally interested In when writing a test componentInstance and nativeElement
ComponentInstance is your component ts file. It's your class declaration in a sense.
NativeElement as the name suggests is the mark-up or your template
I don't think it's possible to do it the way you suggested.
However you could try
const color = window.getComputedStyle(fixture.debugElement.nativeElement.querySelector('label'), ':after').getPropertyValue('background-color');
This will give you a rgb result so for red it would be rgb(255,0,0)
I got this from: How to get pseudo element?
Try this and see if it works. It's not great that we had to access the window element inside of our test but it might solve your issue. Possibly create a better test without having to access the window api i would suggest.

Resources