Browse Source

First pass at CSS identifiers + test to verify they are set. For #2193

pull/2432/head
Gabe Kangas 3 years ago
parent
commit
c231fd3592
No known key found for this signature in database
GPG Key ID: 4345B2060657F330
  1. 2
      test/automated/browser/cypress/e2e/offline/01_offline_basic.cy.js
  2. 44
      test/automated/browser/cypress/e2e/offline/05_offline_identifier_check.cy.js
  3. 24
      test/automated/browser/cypress/e2e/online/05_online_identifier_check.cy.js
  4. 3
      web/components/action-buttons/ActionButton/ActionButton.tsx
  5. 1
      web/components/action-buttons/FollowButton.tsx
  6. 8
      web/components/action-buttons/NotifyButton.tsx
  7. 2
      web/components/modals/FollowModal/FollowModal.tsx
  8. 2
      web/components/ui/CustomPageContent/CustomPageContent.tsx
  9. 4
      web/components/ui/Footer/Footer.tsx
  10. 2
      web/components/ui/Header/Header.tsx
  11. 4
      web/components/ui/Modal/Modal.tsx
  12. 2
      web/components/ui/OfflineBanner/OfflineBanner.tsx
  13. 4
      web/components/ui/followers/FollowerCollection/FollowerCollection.tsx

2
test/automated/browser/cypress/e2e/offline/01_offline_basic.cy.js

@ -38,7 +38,7 @@ describe(`Basic tests`, () => { @@ -38,7 +38,7 @@ describe(`Basic tests`, () => {
});
it('Has correct global header values', () => {
cy.get('.global-header-text').should('have.text', 'New Owncast Server');
cy.get('#global-header-text').should('have.text', 'New Owncast Server');
});
// Offline banner

44
test/automated/browser/cypress/e2e/offline/05_offline_identifier_check.cy.js

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
/*
This test is to verify that the identifiers for specific components are
correctly set. This is to ensure that CSS customizations can be made to the web
UI using these specific IDs and/or class names.
These should be documented so people know how to customize their pages.
If you change one of these identifiers, you must update the documentation.
*/
const identifiers = [
'header', // The entire header component
'footer', // The entire footer component
'#global-header-text', // Just the text in the header
'#offline-banner', // The entire offline banner component
'#custom-page-content', // The entire custom page content component
'#notify-button', // The notify button
'#follow-button', // The follow button
];
describe(`Has correct identifiers for overrides`, () => {
it('Can visit the page', () => {
cy.visit('http://localhost:8080/');
});
// Loop over each identifier and verify it exists.
identifiers.forEach((identifier) => {
it(`Has identifier: ${identifier}`, () => {
cy.get(identifier).should('be.visible');
});
});
// Followers
const followersCollection = '#followers-collection';
it(`Has identifier: ${followersCollection}`, () => {
cy.get('#rc-tabs-1-tab-3').click();
cy.get(followersCollection).should('be.visible');
});
// Modal
const modalContainer = '#modal-container';
it(`Has identifier ${modalContainer}`, () => {
cy.contains('Notify').click();
cy.get(modalContainer, { timeout: 2000 }).should('be.visible');
});
});

24
test/automated/browser/cypress/e2e/online/05_online_identifier_check.cy.js

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
/*
This test is to verify that the identifiers for specific components are
correctly set. This is to ensure that CSS customizations can be made to the web
UI using these specific IDs and/or class names.
These should be documented so people know how to customize their pages.
If you change one of these identifiers, you must update the documentation.
*/
const identifiers = [
'#chat-container', // The entire chat container component
];
describe(`Has correct identifiers for overrides`, () => {
it('Can visit the page', () => {
cy.visit('http://localhost:8080/');
});
// Loop over each identifier and verify it exists.
identifiers.forEach((identifier) => {
it(`Has identifier: ${identifier}`, () => {
cy.get(identifier).should('be.visible');
});
});
});

3
web/components/action-buttons/ActionButton/ActionButton.tsx

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
import { Button } from 'antd';
import { FC } from 'react';
import cn from 'classnames';
import { ExternalAction } from '../../../interfaces/external-action';
import styles from './ActionButton.module.scss';
@ -19,7 +20,7 @@ export const ActionButton: FC<ActionButtonProps> = ({ @@ -19,7 +20,7 @@ export const ActionButton: FC<ActionButtonProps> = ({
return (
<Button
type={primary ? 'primary' : 'default'}
className={`${styles.button}`}
className={cn([`${styles.button}`, 'action-button'])}
onClick={() => externalActionSelected(action)}
style={{ backgroundColor: color }}
>

1
web/components/action-buttons/FollowButton.tsx

@ -16,6 +16,7 @@ export const FollowButton: FC<FollowButtonProps> = ({ onClick, props }) => ( @@ -16,6 +16,7 @@ export const FollowButton: FC<FollowButtonProps> = ({ onClick, props }) => (
className={styles.button}
icon={<HeartFilled />}
onClick={onClick}
id="follow-button"
>
Follow
</Button>

8
web/components/action-buttons/NotifyButton.tsx

@ -9,7 +9,13 @@ export type NotifyButtonProps = { @@ -9,7 +9,13 @@ export type NotifyButtonProps = {
};
export const NotifyButton: FC<NotifyButtonProps> = ({ onClick, text }) => (
<Button type="primary" className={`${styles.button}`} icon={<BellFilled />} onClick={onClick}>
<Button
type="primary"
className={`${styles.button}`}
icon={<BellFilled />}
onClick={onClick}
id="notify-button"
>
{text || 'Notify'}
</Button>
);

2
web/components/modals/FollowModal/FollowModal.tsx

@ -74,7 +74,7 @@ export const FollowModal: FC<FollowModalProps> = ({ handleClose, account, name } @@ -74,7 +74,7 @@ export const FollowModal: FC<FollowModalProps> = ({ handleClose, account, name }
};
return (
<Space direction="vertical">
<Space direction="vertical" id="follow-modal">
<div className={styles.header}>
By following this stream you'll get notified on the Fediverse when it goes live. Now is a
great time to

2
web/components/ui/CustomPageContent/CustomPageContent.tsx

@ -7,7 +7,7 @@ export type CustomPageContentProps = { @@ -7,7 +7,7 @@ export type CustomPageContentProps = {
};
export const CustomPageContent: FC<CustomPageContentProps> = ({ content }) => (
<div className={styles.pageContentContainer}>
<div className={styles.pageContentContainer} id="custom-page-content">
<div className={styles.customPageContent} dangerouslySetInnerHTML={{ __html: content }} />
</div>
);

4
web/components/ui/Footer/Footer.tsx

@ -6,7 +6,7 @@ export type FooterProps = { @@ -6,7 +6,7 @@ export type FooterProps = {
};
export const Footer: FC<FooterProps> = ({ version }) => (
<div className={styles.footer}>
<footer className={styles.footer}>
<span>
Powered by <a href="https://owncast.online">{version}</a>
</span>
@ -21,6 +21,6 @@ export const Footer: FC<FooterProps> = ({ version }) => ( @@ -21,6 +21,6 @@ export const Footer: FC<FooterProps> = ({ version }) => (
Source
</a>
</span>
</div>
</footer>
);
export default Footer;

2
web/components/ui/Header/Header.tsx

@ -23,7 +23,7 @@ export const Header: FC<HeaderComponentProps> = ({ @@ -23,7 +23,7 @@ export const Header: FC<HeaderComponentProps> = ({
<div id="header-logo">
<OwncastLogo variant="contrast" />
</div>
<span className="global-header-text">{name}</span>
<span id="global-header-text">{name}</span>
</div>
{chatAvailable && !chatDisabled && <UserDropdown />}
{!chatAvailable && !chatDisabled && (

4
web/components/ui/Modal/Modal.tsx

@ -71,7 +71,7 @@ export const Modal: FC<ModalProps> = ({ @@ -71,7 +71,7 @@ export const Modal: FC<ModalProps> = ({
centered
destroyOnClose
>
<>
<div id="modal-container">
{loading && (
<Skeleton active={loading} style={{ padding: '10px' }} paragraph={{ rows: 10 }} />
)}
@ -79,7 +79,7 @@ export const Modal: FC<ModalProps> = ({ @@ -79,7 +79,7 @@ export const Modal: FC<ModalProps> = ({
{iframe && <div style={{ display: iframeDisplayStyle }}>{iframe}</div>}
{children && <div className={styles.content}>{children}</div>}
{loading && <Spin className={styles.spinner} spinning={loading} size="large" />}
</>
</div>
</AntModal>
);
};

2
web/components/ui/OfflineBanner/OfflineBanner.tsx

@ -66,7 +66,7 @@ export const OfflineBanner: FC<OfflineBannerProps> = ({ @@ -66,7 +66,7 @@ export const OfflineBanner: FC<OfflineBannerProps> = ({
}
return (
<div className={styles.outerContainer}>
<div id="offline-banner" className={styles.outerContainer}>
<div className={styles.innerContainer}>
<div className={styles.header}>{streamName}</div>
<Divider className={styles.separator} />

4
web/components/ui/followers/FollowerCollection/FollowerCollection.tsx

@ -47,7 +47,7 @@ export const FollowerCollection: FC<FollowerCollectionProps> = ({ name, onFollow @@ -47,7 +47,7 @@ export const FollowerCollection: FC<FollowerCollectionProps> = ({ name, onFollow
}, [followers]);
const noFollowers = (
<div className={styles.noFollowers}>
<div className={styles.noFollowers} id="followers-collection">
<h2>Be the first follower!</h2>
<p>
{name !== 'Owncast' ? name : 'This server'} is a part of the{' '}
@ -74,7 +74,7 @@ export const FollowerCollection: FC<FollowerCollectionProps> = ({ name, onFollow @@ -74,7 +74,7 @@ export const FollowerCollection: FC<FollowerCollectionProps> = ({ name, onFollow
}
return (
<div className={styles.followers}>
<div className={styles.followers} id="followers-collection">
<Row wrap gutter={[10, 10]}>
{followers.map(follower => (
<Col key={follower.link}>

Loading…
Cancel
Save