1

My fixture has a ClientScript that sets an attribute on an element (the element comes from the script doing a document.querySelectorAll(...)):

element.setAttribute("data-foo", 'foo');

Later in testcafe-land when I try to access that element using a Selector it's always null:

const element = await Selector('[data-foo="foo"]')();

I've stuck a debugger statement into my injected ClientScript and as I step thru the function I see the element does indeed get the attribute added but as soon as I let the execution continue and try to find it again in the devtools Console the attribute is gone from the element.

I -think- it has to do with the iframe/shadow DOM? testcafe is creating? I see there is a sub-iframe/execution context in chrome devtools - my ClientScript is being injected into window.top but there is a testcafe-created iframe in the mix too.

ANY THOUGHTS how I can get this to work? I want an injected script to manipulate the DOM (by adding an attribute) that later on I want a testcafe Selector to select. Why doesn't this work and how can I get it working??? thanks!!! Mark

Alex Skorkin
  • 4,264
  • 3
  • 25
  • 47

1 Answers1

1

TestCafe injects custom scripts into the head tag. These scripts are executed before DOM is loaded.

Here is an example of how to manipulate DOM using the client script:

import { Selector } from 'testcafe';

const scriptContent = `
window.addEventListener('DOMContentLoaded', function () {
    var p = document.querySelector('p');
    
    p.setAttribute("data-foo", 'foo');
});
`;

fixture `My fixture`
    .page('https://devexpress.github.io/testcafe/example/')
    .clientScripts({ content: scriptContent });

test('My test', async t => {
    const el = await Selector('[data-foo="foo"]');

    await t
        .expect(el.textContent).eql('This webpage is used as a sample in TestCafe tutorials.');
});
Dmitry Ostashev
  • 2,305
  • 1
  • 5
  • 21