init cypress

This commit is contained in:
nflnkr 2023-10-17 16:43:31 +03:00
parent a0b9aeb191
commit e6d32dd72d
25 changed files with 850 additions and 31454 deletions

2
.gitignore vendored

@ -21,3 +21,5 @@
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*
.idea

8
.idea/.gitignore vendored

@ -1,8 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

@ -1,6 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/squiz.iml" filepath="$PROJECT_DIR$/.idea/squiz.iml" />
</modules>
</component>
</project>

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

10
cypress.config.ts Normal file

@ -0,0 +1,10 @@
import { defineConfig } from "cypress";
export default defineConfig({
e2e: {
baseUrl: 'http://localhost:3000',
viewportWidth: 1440,
viewportHeight: 900,
supportFile: false,
},
});

@ -0,0 +1,52 @@
describe("Quiz preview", () => {
beforeEach(() => {
cy.visit("/list");
cy.get("[data-cy=create-quiz]").click();
cy.get("[data-cy=create-quiz-card]").click();
cy.get("[data-cy=select-quiz-layout-standard]").click();
cy.get("[data-cy=setup-questions]").click();
});
it("container and layout elements should exist", () => {
cy.get("[data-cy=quiz-preview-container]").should("exist");
cy.get("[data-cy=quiz-preview-layout]").should("exist");
});
describe("Variant question", () => {
beforeEach(function fillTitleAndOptions() {
cy.get("[data-cy=expand-question]").click();
cy.get("[data-cy=select-questiontype-variant]").click();
cy.get("[data-cy=quiz-question-card]").eq(0).within(() => {
cy.get("[data-cy=quiz-question-title]").type("Question Title");
cy.get("[data-cy=quiz-variant-question-answer]").eq(0).type("Answer 1{enter}");
cy.get("[data-cy=quiz-variant-question-answer]").eq(1).type("Answer 2{enter}");
cy.get("[data-cy=quiz-variant-question-answer]").eq(2).type("Answer 3");
});
});
it("should contain title and options, and be selected properly", () => {
cy.get("[data-cy=quiz-preview-layout]").within(() => {
cy.get("[data-cy=variant-title]").should("have.text", "Question Title");
cy.get("[data-cy=variant-answer]").eq(0).should("have.text", "Answer 1");
cy.get("[data-cy=variant-answer]").eq(1).should("have.text", "Answer 2");
cy.get("[data-cy=variant-answer]").eq(2).should("have.text", "Answer 3");
cy.get("[data-cy=variant-answer]").eq(0).click();
cy.get("[data-cy=variant-radio]").eq(0).should("be.checked");
cy.get("[data-cy=variant-radio]").eq(1).should("not.be.checked");
cy.get("[data-cy=variant-radio]").eq(2).should("not.be.checked");
cy.get("[data-cy=variant-answer]").eq(1).click();
cy.get("[data-cy=variant-radio]").eq(0).should("not.be.checked");
cy.get("[data-cy=variant-radio]").eq(1).should("be.checked");
cy.get("[data-cy=variant-radio]").eq(2).should("not.be.checked");
cy.get("[data-cy=variant-answer]").eq(2).click();
cy.get("[data-cy=variant-radio]").eq(0).should("not.be.checked");
cy.get("[data-cy=variant-radio]").eq(1).should("not.be.checked");
cy.get("[data-cy=variant-radio]").eq(2).should("be.checked");
});
});
});
});

12
cypress/tsconfig.json Normal file

@ -0,0 +1,12 @@
{
"compilerOptions": {
"noEmit": true,
"types": [
"cypress"
]
},
"include": [
"../node_modules/cypress",
"./**/*.ts"
]
}

31358
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -47,23 +47,14 @@
"start": "craco start", "start": "craco start",
"build": "craco build", "build": "craco build",
"test": "craco test", "test": "craco test",
"eject": "craco eject" "eject": "craco eject",
"cypress:open": "cypress open"
}, },
"eslintConfig": { "eslintConfig": {
"extends": [ "extends": [
"react-app", "react-app",
"react-app/jest" "react-app/jest"
], ]
"rules": {
"quotes": [
"warn",
"double",
{
"avoidEscape": true,
"allowTemplateLiterals": true
}
]
}
}, },
"browserslist": { "browserslist": {
"production": [ "production": [
@ -81,6 +72,7 @@
"@emoji-mart/data": "^1.1.2", "@emoji-mart/data": "^1.1.2",
"@emoji-mart/react": "^1.1.1", "@emoji-mart/react": "^1.1.1",
"@types/react-beautiful-dnd": "^13.1.4", "@types/react-beautiful-dnd": "^13.1.4",
"craco-alias": "^3.0.1" "craco-alias": "^3.0.1",
"cypress": "^13.3.1"
} }
} }

13
src/mui.d.ts vendored

@ -9,7 +9,7 @@ declare module "@mui/material/styles" {
grey1: Palette["primary"], grey1: Palette["primary"],
grey2: Palette["primary"], grey2: Palette["primary"],
grey3: Palette["primary"], grey3: Palette["primary"],
grey4: Palette ["primary"], grey4: Palette["primary"],
orange: Palette["primary"], orange: Palette["primary"],
navbarbg: Palette["primary"], navbarbg: Palette["primary"],
} }
@ -21,7 +21,7 @@ declare module "@mui/material/styles" {
grey1?: PaletteOptions["primary"], grey1?: PaletteOptions["primary"],
grey2?: PaletteOptions["primary"], grey2?: PaletteOptions["primary"],
grey3?: PaletteOptions["primary"], grey3?: PaletteOptions["primary"],
grey4?: PaletteOptions ["primary"], grey4?: PaletteOptions["primary"],
orange?: PaletteOptions["primary"], orange?: PaletteOptions["primary"],
navbarbg?: PaletteOptions["primary"], navbarbg?: PaletteOptions["primary"],
} }
@ -40,4 +40,11 @@ declare module "@mui/material/Typography" {
infographic: true; infographic: true;
p1: true; p1: true;
} }
} }
type DataAttributeKey = `data-${string}`;
declare module 'react' {
interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {
[dataAttribute: DataAttributeKey]: unknown;
}
}

@ -200,6 +200,7 @@ export const AnswerItem = ({
}} }}
inputProps={{ inputProps={{
sx: { fontSize: "18px", lineHeight: "21px", py: 0, ml: "13px" }, sx: { fontSize: "18px", lineHeight: "21px", py: 0, ml: "13px" },
"data-cy": "quiz-variant-question-answer",
}} }}
/> />
{additionalMobile} {additionalMobile}

@ -168,6 +168,7 @@ export default function QuestionsPageCard({
<> <>
<Paper <Paper
id={String(totalIndex)} id={String(totalIndex)}
data-cy="quiz-question-card"
sx={{ sx={{
maxWidth: "796px", maxWidth: "796px",
width: "100%", width: "100%",
@ -245,6 +246,7 @@ export default function QuestionsPageCard({
py: 0, py: 0,
paddingLeft: question.type.length === 0 ? 0 : "18px", paddingLeft: question.type.length === 0 ? 0 : "18px",
}, },
"data-cy": "quiz-question-title",
}} }}
/> />
</FormControl> </FormControl>
@ -260,6 +262,7 @@ export default function QuestionsPageCard({
<IconButton <IconButton
sx={{ padding: "0", margin: "5px" }} sx={{ padding: "0", margin: "5px" }}
disableRipple disableRipple
data-cy="expand-question"
onClick={() => onClick={() =>
updateQuestionsList<QuizQuestionInitial>(quizId, totalIndex, { updateQuestionsList<QuizQuestionInitial>(quizId, totalIndex, {
expanded: !question.expanded, expanded: !question.expanded,

@ -110,6 +110,7 @@ export default function TypeQuestions({ totalIndex }: Props) {
{BUTTON_TYPE_QUESTIONS.map(({ icon, title, value }) => ( {BUTTON_TYPE_QUESTIONS.map(({ icon, title, value }) => (
<QuestionsMiniButton <QuestionsMiniButton
key={title} key={title}
dataCy={`select-questiontype-${value}`}
onClick={() => { onClick={() => {
const question = { ...listQuestions[quizId][totalIndex] }; const question = { ...listQuestions[quizId][totalIndex] };

@ -34,6 +34,7 @@ export default function FirstQuiz() {
</Typography> </Typography>
<Button <Button
variant="contained" variant="contained"
data-cy="create-quiz"
onClick={() => { onClick={() => {
navigate(`/setting/${createBlank()}`); navigate(`/setting/${createBlank()}`);
}} }}

@ -723,6 +723,7 @@ export default function StartPageSettings() {
/> />
<Button <Button
variant="contained" variant="contained"
data-cy="setup-questions"
onClick={() => { onClick={() => {
let SPageClone = listQuizes[params].config; let SPageClone = listQuizes[params].config;
SPageClone.startpage.background.desktop = SPageClone.startpage.background.desktop =

@ -22,6 +22,7 @@ export default function StepOne() {
> >
<Button <Button
variant="text" variant="text"
data-cy="create-quiz-card"
onClick={() => { onClick={() => {
let SPageClone = listQuizes[params].config; let SPageClone = listQuizes[params].config;
SPageClone.type = "quize"; SPageClone.type = "quize";

@ -21,6 +21,7 @@ export default function Steptwo () {
mt: "40px", mt: "40px",
}}> }}>
<Button variant='text' <Button variant='text'
data-cy="select-quiz-layout-standard"
onClick={() => { onClick={() => {
updateQuizesList(params, {startpage: "standard"}) updateQuizesList(params, {startpage: "standard"})
}} }}
@ -44,4 +45,4 @@ export default function Steptwo () {
</Box> </Box>
</Box> </Box>
) )
} }

@ -7,15 +7,17 @@ interface QuestionsMiniButtonProps {
icon: ReactNode; icon: ReactNode;
text: string; text: string;
onClick: () => void; onClick: () => void;
dataCy?: string;
} }
export default function QuestionsMiniButton({ icon, text, onClick }: QuestionsMiniButtonProps) { export default function QuestionsMiniButton({ icon, text, onClick, dataCy }: QuestionsMiniButtonProps) {
const theme = useTheme(); const theme = useTheme();
return ( return (
<> <>
<Button <Button
variant="outlined" variant="outlined"
data-cy={dataCy}
sx={{ sx={{
padding: "26px 15px 15px 15px", padding: "26px 15px 15px 15px",
display: "flex", display: "flex",

@ -47,6 +47,7 @@ export default function QuizPreview() {
return ( return (
<Box <Box
ref={rndParentRef} ref={rndParentRef}
data-cy="quiz-preview-container"
sx={{ sx={{
position: "fixed", position: "fixed",
top: NAVBAR_HEIGHT + DRAG_PARENT_MARGIN, top: NAVBAR_HEIGHT + DRAG_PARENT_MARGIN,

@ -58,14 +58,17 @@ export default function QuizPreviewLayout() {
}, [currentQuizStep, maxCurrentQuizStep]); }, [currentQuizStep, maxCurrentQuizStep]);
return ( return (
<Paper sx={{ <Paper
height: "100%", data-cy="quiz-preview-layout"
display: "flex", sx={{
flexDirection: "column", height: "100%",
flexGrow: 1, display: "flex",
borderRadius: "12px", flexDirection: "column",
pointerEvents: "auto", flexGrow: 1,
}}> borderRadius: "12px",
pointerEvents: "auto",
}}
>
<Box sx={{ <Box sx={{
p: "16px", p: "16px",
whiteSpace: "break-spaces", whiteSpace: "break-spaces",

@ -17,23 +17,37 @@ export default function Variant({ question }: Props) {
return ( return (
<FormControl fullWidth> <FormControl fullWidth>
<FormLabel id="quiz-question-radio-group">{question.title}</FormLabel> <FormLabel
id="quiz-question-radio-group"
data-cy="variant-title"
>{question.title}</FormLabel>
<RadioGroup <RadioGroup
aria-labelledby="quiz-question-radio-group" aria-labelledby="quiz-question-radio-group"
value={value} value={value}
onChange={handleChange} onChange={handleChange}
> >
{question.content.variants.map((variant, index) => ( {question.content.variants.map((variant, index) => (
<FormControlLabel key={index} value={variant.answer} control={<Radio />} label={ <FormControlLabel
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}> key={index}
<Typography>{variant.answer}</Typography> value={variant.answer}
<Tooltip title={variant.hints} placement="right"> control={<Radio
<Box> inputProps={{
<InfoIcon /> "data-cy": "variant-radio",
</Box> }}
</Tooltip> />}
</Box> label={
} /> <Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
<Typography
data-cy="variant-answer"
>{variant.answer}</Typography>
<Tooltip title={variant.hints} placement="right">
<Box>
<InfoIcon />
</Box>
</Tooltip>
</Box>
}
/>
))} ))}
</RadioGroup> </RadioGroup>
</FormControl> </FormControl>

@ -19,9 +19,14 @@
"resolveJsonModule": true, "resolveJsonModule": true,
"isolatedModules": true, "isolatedModules": true,
"noEmit": true, "noEmit": true,
"jsx": "react-jsx" "jsx": "react-jsx",
}, },
"include": [ "include": [
"src" "src",
],
"exclude": [
"cypress.config.ts",
"cypress",
"node_modules",
] ]
} }

721
yarn.lock

File diff suppressed because it is too large Load Diff