iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🏂

Testing RSS and XML with Cypress

に公開

I recently had the opportunity to test XML format outputs such as RSS and sitemaps using Cypress, so I'll briefly document how to do it.

Getting an XMLDocument from an XML string

Testing whether the requested XML page has the intended content is difficult if handled as a plain string. By first generating an XMLDocument object from the string, you can easily write tests using methods like document.querySelector().

To get an XMLDocument from a string, use the parseFromString() method of DOMParser. No external libraries are required as it is natively supported by modern browsers.

In the case of Cypress, you can access the XML URL and then retrieve the XMLDocument as follows.

const parser = new DOMParser();

cy.request('URL of the XML page').then((res) => {
  const doc = parser.parseFromString(res.body, 'application/xml');
});

Writing an actual RSS test

For example, suppose you have an RSS page like the following.

/rss.xml
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<channel>
  <title>RSS Title</title>
  <description>RSS Description</description>
  <link>https://example.com</link>
  <item>
    <title>item0 Title</title>
    <description>item0 Description</description>
    <link>http://example.com/item0</link>
    <pubDate>Fri, 04 Mar 2022 02:10:52 GMT</pubDate>
  </item>
  <item>
    <title>item1 Title</title>
    <description>item1 Description</description>
    <link>http://example.com/item1</link>
    <pubDate>Fri, 04 Mar 2022 02:10:52 GMT</pubDate>
  </item>
…omitted…

Let's write a simple test in Cypress to check if the content of this RSS is as intended.

rss.spec.ts
const parser = new DOMParser();

it('RSS is output correctly', () => {
  cy.request('/rss.xml').then((res) => {
    const doc = parser.parseFromString(res.body, 'application/xml');
    // Is the title correct?
    expect(doc.querySelector('channel > title')?.textContent).to.eq('RSS Title');
    // Is the link URL correct?
    expect(doc.querySelector('channel > link')?.textContent).to.eq('https://example.com');
    // Get a list of items to test each item
    const items = doc.querySelectorAll('item');
    // Is the number of items correct?
    expect(items.length).to.eq(2);
    // Does the title of the first item contain the correct string?
    expect(items[0].querySelector('title')?.textContent).to.contain('item0 Title')
   // Does the title of the second item contain the correct string?
    expect(items[1].querySelector('title')?.textContent).to.contain('item1 Title');
  });
});

In this way, you can test XML just like you would with HTML.

As a side note, it's a good idea to check if the output content complies with RSS standards using the W3C Feed Validation Service. Since they provide an API, I'm planning to see if I can automate this check using GitHub Actions or similar in the future.

Discussion