import mocha from 'mocha'; import chai from 'chai'; import { getNode } from './node'; import { addFinder } from '@iconify/iconify/lib/finder'; import { FakeData, setFakeData, prepareQuery, sendQuery } from './fake-api'; import { API } from '@iconify/core/lib/api/'; import { setDefaultAPIModule } from '@iconify/core/lib/api/modules'; import { setAPIConfig } from '@iconify/core/lib/api/config'; import { coreModules } from '@iconify/core/lib/modules'; import { finder as iconifyFinder } from '@iconify/iconify/lib/finders/iconify'; import { finder as iconifyIconFinder } from '@iconify/iconify/lib/finders/iconify-icon'; import { browserModules } from '@iconify/iconify/lib/modules'; import { scanDOM } from '@iconify/iconify/lib/scan'; const expect = chai.expect; // Add finders addFinder(iconifyFinder); addFinder(iconifyIconFinder); // Set API setDefaultAPIModule({ prepare: prepareQuery, send: sendQuery, }); coreModules.api = API; let prefixCounter = 0; function nextPrefix(): string { return 'scan-dom-api-' + prefixCounter++; } describe('Scanning DOM with API', () => { it('Scan DOM with API', (done) => { const provider = nextPrefix(); const prefix1 = nextPrefix(); const prefix2 = nextPrefix(); // Set fake API hosts to make test reliable setAPIConfig(provider, { resources: ['https://api1.local', 'https://api2.local'], }); // Set icons, load them with various delay const data1: FakeData = { icons: ['home', 'account-cash'], delay: 100, data: { prefix: prefix1, icons: { 'account-cash': { body: '', }, 'home': { body: '', }, }, width: 24, height: 24, }, }; setFakeData(provider, prefix1, data1); const data2: FakeData = { icons: ['account', 'account-box'], delay: 500, data: { prefix: prefix2, icons: { 'account-box': { body: '', }, 'account': { body: '', }, }, width: 24, height: 24, }, }; setFakeData(provider, prefix2, data2); const node = getNode('scan-dom'); node.innerHTML = '

Testing scanning DOM with API

    ' + '
  • Inline icons:' + ' ' + ' ' + '
  • ' + '
  • Block icons:' + ' ' + ' ' + '
  • ' + '
'; browserModules.root = node; scanDOM(); // First API response should have loaded setTimeout(() => { const elements = node.querySelectorAll('svg.iconify'); expect(elements.length).to.be.equal( 2, 'Expected to find 2 rendered SVG elements' ); }, 200); // Second API response should have loaded setTimeout(() => { const elements = node.querySelectorAll('svg.iconify'); expect(elements.length).to.be.equal( 4, 'Expected to find 4 rendered SVG elements' ); done(); }, 700); }); it('Changing icon name before it loaded', (done) => { const provider = nextPrefix(); const prefix1 = nextPrefix(); const prefix2 = nextPrefix(); // Set fake API hosts to make test reliable setAPIConfig(provider, { resources: ['https://api1.local', 'https://api2.local'], }); // Set icons, load them with various delay const data1: FakeData = { icons: ['home', 'account-cash'], delay: 100, data: { prefix: prefix1, icons: { 'account-cash': { body: '', }, 'home': { body: '', }, }, width: 24, height: 24, }, }; setFakeData(provider, prefix1, data1); const data2: FakeData = { icons: ['account', 'account-box'], delay: 500, data: { prefix: prefix2, icons: { 'account-box': { body: '', }, 'account': { body: '', }, }, width: 24, height: 24, }, }; setFakeData(provider, prefix2, data2); const data1b: FakeData = { icons: ['account', 'account-box'], delay: 800, // +100ms for first query data: { prefix: prefix1, icons: { 'account-box': { body: '', }, 'account': { body: '', }, }, width: 24, height: 24, }, }; setFakeData(provider, prefix1, data1b); const node = getNode('scan-dom'); node.innerHTML = '

Testing scanning DOM with API: renamed icon

    ' + '
  • Default finder:' + ' ' + ' ' + '
  • ' + '
  • IconifyIcon finder:' + ' ' + ' ' + '
  • ' + '
'; browserModules.root = node; scanDOM(); // Make sure no icons were rendered yet const elements = node.querySelectorAll('svg.iconify'); expect(elements.length).to.be.equal( 0, 'Expected to find 0 rendered SVG elements' ); // Change icon name const icon = node.querySelector('iconify-icon[title]'); expect(icon).to.not.be.equal(null); expect(icon.getAttribute('class')).to.be.equal('third-icon'); icon.setAttribute( 'data-icon', '@' + provider + ':' + prefix1 + ':account' ); // First API response should have loaded, but only 1 icon should have been rendered setTimeout(() => { // Loaded for prefix1: account-cash, home // Loaded for prefix2: - const elements = node.querySelectorAll('svg.iconify'); expect(elements.length).to.be.equal(1, '200ms delay error'); }, 200); // Second API response should have loaded setTimeout(() => { // Loaded for prefix1: account-cash, home // Loaded for prefix2: account, account-box const elements = node.querySelectorAll('svg.iconify'); expect(elements.length).to.be.equal(3, '700ms delay error'); }, 700); // Renamed icon from first API response setTimeout(() => { // Loaded for prefix1: account-cash, home, account-box, account // Loaded for prefix2: account, account-box const elements = node.querySelectorAll('svg.iconify'); expect(elements.length).to.be.equal(4, '1000ms delay error'); done(); }, 1100); }); it('Changing icon name before it loaded to invalid name', (done) => { const provider = nextPrefix(); const prefix1 = nextPrefix(); const prefix2 = nextPrefix(); // Set fake API hosts to make test reliable setAPIConfig(provider, { resources: ['https://api1.local', 'https://api2.local'], }); // Set icons, load them with various delay const data1: FakeData = { icons: ['home', 'account-cash'], delay: 100, data: { prefix: prefix1, icons: { 'account-cash': { body: '', }, 'home': { body: '', }, }, width: 24, height: 24, }, }; setFakeData(provider, prefix1, data1); const data2: FakeData = { icons: ['account', 'account-box'], delay: 500, data: { prefix: prefix2, icons: { 'account-box': { body: '', }, 'account': { body: '', }, }, width: 24, height: 24, }, }; setFakeData(provider, prefix2, data2); const node = getNode('scan-dom'); node.innerHTML = '

Testing scanning DOM with API: invalid name

    ' + '
  • Inline icons:' + ' ' + ' ' + '
  • ' + '
  • Block icons:' + ' ' + ' ' + '
  • ' + '
'; browserModules.root = node; scanDOM(); // Change icon name const icon = node.querySelector('iconify-icon[title]'); expect(icon).to.not.be.equal(null); icon.setAttribute('data-icon', '@' + provider + ':foo'); // First API response should have loaded, but only 1 icon setTimeout(() => { const elements = node.querySelectorAll('svg.iconify'); expect(elements.length).to.be.equal(1); }, 200); // Second API response should have loaded setTimeout(() => { const elements = node.querySelectorAll('svg.iconify'); expect(elements.length).to.be.equal(3); done(); }, 700); }); });