Compare commits

...

5 Commits

Author SHA1 Message Date
Daniel D Orlando
bb3c28b723 fix: use cjs extension for commonjs files 2023-05-20 08:54:58 -07:00
Danny Avila
5964b71e14 Setup tests with new user system (#344)
* chore(.gitignore): add auth.json to gitignore
test(landing.spec.js): remove commented out code and add check for landing page title
test(login.spec.js): add test for login page title
feat(package.json): add e2e:auth script to generate auth.json storage file for e2e tests

* test(landing.spec.js): add beforeEach hook to create a new browser context with auth.json storage state
test(landing.spec.js): change test name from 'landing page' to 'Landing title'
fix(package.json): change e2e:auth script to save auth.json in e2e directory
2023-05-20 09:00:45 -04:00
Danny Avila
8c7ad09977 style(mobile.css): decrease z-index of .nav-mask to 35 (#337) 2023-05-19 21:09:07 -04:00
Danny Avila
cef2668f53 style(NewConversationMenu): add z-index to Dialog and DropdownMenuContent (#335)
style(mobile.css): decrease z-index of .nav to 40
2023-05-19 19:58:53 -04:00
Danny Avila
ab7cfc6041 Hotfix (#334)
* style(NavLinks.jsx): add 'as="div"' to Menu.Item components
refactor(Nav.jsx): remove unused code and add isMobile function to check if user is on mobile device

* conditionally render menuitem with search

---------

Co-authored-by: stunt_pilot <twitchstuntpilot@gmail.com>
2023-05-19 19:37:56 -04:00
12 changed files with 72 additions and 37 deletions

2
.gitignore vendored
View File

@@ -64,4 +64,4 @@ src/style - official.css
# meilisearch
meilisearch
data.ms/*
auth.json

View File

@@ -122,7 +122,7 @@ export default function NewConversationMenu() {
});
return (
<Dialog>
<Dialog className="z-[100]">
<DropdownMenu open={menuOpen} onOpenChange={setMenuOpen}>
<DropdownMenuTrigger asChild>
<Button
@@ -136,7 +136,7 @@ export default function NewConversationMenu() {
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent
className="min-w-[300px] dark:bg-gray-700"
className="min-w-[300px] dark:bg-gray-700 z-[100]"
onCloseAutoFocus={(event) => event.preventDefault()}
>
<DropdownMenuLabel

View File

@@ -69,10 +69,12 @@ export default function NavLinks({ clearSearch, isSearchEnabled }) {
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="absolute bottom-full left-0 z-20 mb-2 w-full translate-y-0 overflow-hidden rounded-md bg-[#050509] py-1.5 opacity-100 outline-none">
<Menu.Item>
{!!isSearchEnabled && <SearchBar clearSearch={clearSearch} />}
</Menu.Item>
<Menu.Item>
{isSearchEnabled && (
<Menu.Item>
<SearchBar clearSearch={clearSearch} />
</Menu.Item>
)}
<Menu.Item as="div">
<NavLink
className={cn(
'flex w-full cursor-pointer items-center gap-3 px-3 py-3 text-sm text-white transition-colors duration-200 hover:bg-gray-700',
@@ -84,10 +86,10 @@ export default function NavLinks({ clearSearch, isSearchEnabled }) {
/>
</Menu.Item>
<div className="my-1.5 h-px bg-white/20" role="none" />
<Menu.Item>
<Menu.Item as="div">
<DarkMode />
</Menu.Item>
<Menu.Item>
<Menu.Item as="div">
<NavLink
className="flex w-full cursor-pointer items-center gap-3 px-3 py-3 text-sm text-white transition-colors duration-200 hover:bg-gray-700"
svg={() => <TrashIcon />}
@@ -96,7 +98,7 @@ export default function NavLinks({ clearSearch, isSearchEnabled }) {
/>
</Menu.Item>
<div className="my-1.5 h-px bg-white/20" role="none" />
<Menu.Item>
<Menu.Item as="div">
<Logout />
</Menu.Item>
</Menu.Items>

View File

@@ -13,25 +13,25 @@ import { useAuthContext } from '~/hooks/AuthContext';
import { ThemeContext } from '~/hooks/ThemeContext';
import { cn } from '~/utils/';
import resolveConfig from 'tailwindcss/resolveConfig';
const tailwindConfig = import('../../../tailwind.config.cjs');
const fullConfig = resolveConfig(tailwindConfig);
// import resolveConfig from 'tailwindcss/resolveConfig';
// const tailwindConfig = import('../../../tailwind.config.cjs');
// const fullConfig = resolveConfig(tailwindConfig);
export const getBreakpointValue = (value) =>
+fullConfig.theme.screens[value].slice(0, fullConfig.theme.screens[value].indexOf('px'));
// export const getBreakpointValue = (value) =>
// +fullConfig.theme.screens[value].slice(0, fullConfig.theme.screens[value].indexOf('px'));
export const getCurrentBreakpoint = () => {
let currentBreakpoint;
let biggestBreakpointValue = 0;
for (const breakpoint of Object.keys(fullConfig.theme.screens)) {
const breakpointValue = getBreakpointValue(breakpoint);
if (breakpointValue > biggestBreakpointValue && window.innerWidth >= breakpointValue) {
biggestBreakpointValue = breakpointValue;
currentBreakpoint = breakpoint;
}
}
return currentBreakpoint;
};
// export const getCurrentBreakpoint = () => {
// let currentBreakpoint;
// let biggestBreakpointValue = 0;
// for (const breakpoint of Object.keys(fullConfig.theme.screens)) {
// const breakpointValue = getBreakpointValue(breakpoint);
// if (breakpointValue > biggestBreakpointValue && window.innerWidth >= breakpointValue) {
// biggestBreakpointValue = breakpointValue;
// currentBreakpoint = breakpoint;
// }
// }
// return currentBreakpoint;
// };
export default function Nav({ navVisible, setNavVisible }) {
const [isHovering, setIsHovering] = useState(false);
@@ -146,9 +146,23 @@ export default function Nav({ navVisible, setNavVisible }) {
setNavVisible((prev) => !prev);
};
// useEffect(() => {
// let currentBreakpoint = getCurrentBreakpoint();
// if (currentBreakpoint === 'sm') {
// setNavVisible(false);
// } else {
// setNavVisible(true);
// }
// }, [conversationId, setNavVisible]);
const isMobile = () => {
const userAgent = typeof window.navigator === 'undefined' ? '' : navigator.userAgent;
const mobileRegex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile|mobile|CriOS/i;
return mobileRegex.test(userAgent);
};
useEffect(() => {
let currentBreakpoint = getCurrentBreakpoint();
if (currentBreakpoint === 'sm') {
if (isMobile()) {
setNavVisible(false);
} else {
setNavVisible(true);

View File

@@ -45,7 +45,7 @@
.nav {
position: fixed;
z-index: 999;
z-index: 40;
left: calc(-100%);
top: 0;
width: calc(100% - 60px);
@@ -74,7 +74,7 @@
}
.nav-mask {
position: fixed;
z-index: 996;
z-index: 35;
left: 0;
right: 0;
top: 0;

View File

@@ -1,9 +1,18 @@
import { expect, test } from '@playwright/test';
test('landing page', async ({ page }) => {
await page.goto('http://localhost:3080/');
// expect (await page.title()).toBe('ChatGPT Clone');
expect(await page.textContent('#landing-title')).toBe(
import.meta.env.VITE_APP_TITLE || 'ChatGPT Clone'
);
test.describe('Landing suite', () => {
let myBrowser;
test.beforeEach(async ({ browser }) => {
myBrowser = await browser.newContext({
storageState: 'e2e/auth.json',
});
});
test('Landing title', async () => {
const page = await myBrowser.newPage();
await page.goto('http://localhost:3080/');
const pageTitle = await page.textContent('#landing-title')
expect(pageTitle.length).toBeGreaterThan(0);
});
});

9
e2e/specs/login.spec.js Normal file
View File

@@ -0,0 +1,9 @@
import { expect, test } from '@playwright/test';
test('landing page', async ({ page }) => {
await page.goto('http://localhost:3080/');
const pageTitle = await page.$eval('h1', pageTitle => pageTitle.textContent);
console.log('pageTitle', pageTitle);
expect(pageTitle.length).toBeGreaterThan(0);
expect(pageTitle).toEqual('Welcome back');
});

View File

@@ -15,6 +15,7 @@
"e2e:update": "playwright test --config=e2e/playwright.config.js --update-snapshots",
"e2e:debug": "cross-env PWDEBUG=1 playwright test --config=e2e/playwright.config.js",
"e2e:report": "npx playwright show-report e2e/playwright-report",
"e2e:auth": "npx playwright codegen --save-storage=e2e/auth.json http://localhost:3080/",
"prepare": "husky install",
"format": "prettier-eslint --write \"{,!(node_modules)/**/}*.{js,jsx,ts,tsx}\""
},