eavichay / showroom

Universal development and automated test environment for web components
https://showroomjs.com
Apache License 2.0
88 stars 7 forks source link

Feature Request: findAll #10

Open msteller-connyun opened 5 years ago

msteller-connyun commented 5 years ago

At the moment it’s only possible to query a single element, after the find method based on querySelector.

For testing components with tables, or lists it would be very usefull if there would be an findAll all query, based on querySelectorAll which returns an array.

Example:

    const result = await (await showroom.utils.findAll('//td')).getProperty('innerText‘);
    expect(result).toBe(['hello', 'world']);
msteller-connyun commented 5 years ago

I found a workaround with https://www.npmjs.com/package/query-selector-shadow-dom


const showroom = require('showroom/puppeteer')();
const path = require('path');

describe('Calendar graph', async () => {

  beforeAll(async () => {
    await showroom.start();
    await showroom.page.addScriptTag({
      path: path.join(process.cwd(), 'node_modules/query-selector-shadow-dom/dist/querySelectorShadowDom.js')
    })
  });

  beforeEach(async () => {
    await showroom.utils.setTestSubject('calendar-graph');
  });

  afterAll(async ()=>{
    await showroom.stop();
  });

  test('should show data', async () => {
    await showroom.utils.trigger('initStatusMapping');
    await showroom.utils.trigger('initData');

    const foo = await showroom.page.evaluate(()=>querySelectorShadowDom.querySelectorAllDeep('calendar-graph .css-td').map(item=>item.innerText));

    expect(foo).toBe(['hello', 'world']);
  });
});

``
eavichay commented 5 years ago

@msteller-connyun I'm glad you found a workaround. If I would add findAll with shadow path then the recursive search would be very laggy and might take too much time.

Showroom is meant for running unit-tests on a single-component level. If you would like to add utils I would be happy for PRs or suggestions (via issues).

Happy testing.

P.S. I have started working on findAll with one major limitation: until the last '//' shadow path in the search it performs showroom.find and then concatenates the rest of the query as querySelectorAll. Will branch this pretty soon.

msteller-connyun commented 5 years ago

I think your major limitation is fine for me, because I need findAll for unit testing data strucutres, like tables.

eavichay commented 5 years ago

@msteller-connyun I would like to know what was your technique of injecting the deep-query script. Was it in the .showroom/config.js file?

msteller-connyun commented 5 years ago

Hello @eavichay

I did it this way

  beforeAll(async () => {
    await showroom.start();
    await loadLibs();
  });

  test('should show banner', async () => {
    const expectedResult = ['no-display'];
    await showroom.utils.trigger('init');
    const result = await showroom.page.evaluate(() => [...querySelectorShadowDom.querySelectorDeep('cy-google-analytics .ga-banner').classList]);
    expect(result).toEqual(expect.not.arrayContaining(expectedResult));
  });

async function loadLibs() {
  return new Promise(async (resolve) => {
    await showroom.page.addScriptTag({
      path: path.join(process.cwd(), 'node_modules/query-selector-shadow-dom/dist/querySelectorShadowDom.js')
    });
    resolve();
  });
}
eavichay commented 5 years ago

Awesome. Basically any utils/scripts can be loaded using the config.js file. You can declare script sources that will be added as tags in the HTML.

I know there are yet undocumented features, but this eventually will be fully documented, perhaps with help from the community.

Thanks for the heads-up.

msteller-connyun commented 5 years ago

yeahh... but it’s still painful to use for the selectors an evaluate(). The load a third party library for the findAll is just a workaround.

eavichay commented 5 years ago

👍

msteller-connyun commented 5 years ago

So.. you closed that ticket. Does this mean there will be no native findAll support in showroom?