Skip to content

Instantly share code, notes, and snippets.

@harrylincoln
Created February 11, 2025 23:27
Show Gist options
  • Save harrylincoln/f3a58a10841586847dc19c1daa17b1c0 to your computer and use it in GitHub Desktop.
Save harrylincoln/f3a58a10841586847dc19c1daa17b1c0 to your computer and use it in GitHub Desktop.
Scrape storybook icons node script
const { chromium } = require('playwright');
const fs = require('fs');
const path = require('path');
const URL = 'https://orgvue-qa.eu-west-1.concentra.io/app/primitive-components/1.0.0/?path=/story/components-icon--actions';
async function scrapeSVGs() {
const browser = await chromium.launch({ headless: false }); // Change to true if you want headless mode
const page = await browser.newPage();
console.log('Opening Storybook page...');
await page.goto(URL, { waitUntil: 'domcontentloaded' });
console.log('Waiting for Storybook UI to load...');
await page.waitForSelector('iframe', { timeout: 60000 }); // Wait for iframe
// Find the iframe
const iframeElement = await page.$('iframe'); // Grabbing the first iframe
if (!iframeElement) {
console.error('Iframe not found!');
await browser.close();
return;
}
const iframe = await iframeElement.contentFrame(); // Get the content inside iframe
if (!iframe) {
console.error('Could not get iframe content!');
await browser.close();
return;
}
console.log('Waiting for icons to appear inside iframe...');
// THIS SELECTOR WILL ALMOST CERTAINLY NEED TO CHANGE BASED ON MARKUP GENERATED BY STORYBOOK
await iframe.waitForSelector('#storybook-root span[role="img"] svg', { timeout: 60000 });
console.log('Extracting SVGs...');
const svgs = await iframe.evaluate(() => {
const icons = {};
// Loop through all the spans that represent icons
document.querySelectorAll('#storybook-root span[role="img"]').forEach(span => {
const ariaLabel = span.getAttribute('aria-label')?.trim().toLowerCase().replace(/\s+/g, '-') || 'unnamed-icon';
const svg = span.querySelector('svg');
if (svg) {
let svgContent = svg.outerHTML.trim();
// Ensure unique filenames
let filename = ariaLabel;
let counter = 1;
while (icons[filename]) {
filename = `${ariaLabel}-${counter}`;
counter++;
}
icons[filename] = svgContent;
}
});
return Object.entries(icons).map(([filename, content]) => ({
filename: `${filename}.svg`,
content
}));
});
console.log(`Found ${svgs.length} unique SVGs.`);
if (svgs.length > 0) saveSVGs(svgs);
await browser.close();
console.log('✅ Done!');
}
function saveSVGs(svgs) {
const outputDir = './svgs';
if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir);
svgs.forEach(({ filename, content }) => {
fs.writeFileSync(`${outputDir}/${filename}`, content, 'utf8');
console.log(`Saved: ${filename}`);
});
}
scrapeSVGs().catch(console.error);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment