-
Notifications
You must be signed in to change notification settings - Fork 172
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[1단계 - 자동차 경주 구현] 인치(한창희) 미션 제출합니다. #20
Changes from 63 commits
484f993
21fe6b8
9238fda
b96b19c
bcb5527
895b750
54a64e5
8c815e8
b245d23
2bb1f02
4620fb2
e545664
856b97c
8de0a1e
50ee2ae
abcfa48
f8f46e6
1006b72
024fb2d
1fc175c
9a065cf
7fa13ca
93662c3
1028d1d
d4d428c
b48d473
8f6959f
206f940
326eade
9285a4b
414b2d5
a54b1d5
6b09abc
cebaaef
b563104
b1ab712
bb7febe
539787f
ae4c2a2
d7075e8
a7dcb36
e68b8f3
8378157
e1ee575
6f45692
b941e8b
74e3f22
00baf1d
e1609c4
7788178
6836ad3
243ca54
fdc4163
7d0f807
66e138c
472da37
f671b28
f9f8e0e
d23557c
f393909
ebd4322
7f79771
24853fe
2e8db23
5d1244f
6829525
bbf60c6
f3b9498
297607c
349075b
a26b91b
8fea822
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"name": "Using fixtures to represent data", | ||
"email": "hello@cypress.io", | ||
"body": "Fixtures are a great way to mock data for responses to routes" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
describe("ui-play", () => { | ||
before(() => { | ||
cy.visit("http://localhost:5500/"); | ||
}); | ||
|
||
it("자동차 섹션을 입력하고 버튼을 클릭하면 횟수 영역이 보여진다", () => { | ||
cy.get("#car-input").type("a,b,c,d"); | ||
cy.get("#car-btn").click(); | ||
cy.get("#count").should("have.css", "display", "block"); | ||
}); | ||
|
||
it("시도 횟수를 입력하고 버튼을 클릭하면 진행 영역이 보여진다", () => { | ||
cy.get("#count-input").type(5); | ||
cy.get("#count-btn").click(); | ||
cy.get("#process").should("have.css", "display", "block"); | ||
}); | ||
|
||
it("자동차 이름을 입력한 순서대로 자동차들을 생성한다", () => { | ||
const cars = ["a", "b", "c", "d"]; | ||
cy.get(".car-player").each((v, i, arr) => { | ||
cy.get(v).should("have.text", cars[i]); | ||
}); | ||
}); | ||
|
||
it("시도 횟수보다 화살표의 개수가 적거나 같아야한다", () => { | ||
cy.get(".process-car").each(v => { | ||
if (v.find(".forward-icon").length > 0) { | ||
cy.get(v).find(".forward-icon").its("length").should("be.lte", 5); | ||
} | ||
}); | ||
}); | ||
|
||
it("가장많은 화살표를 가지고 있는 차의 이름이 우승자에 있어야 한다", () => { | ||
let largestCount = 0; | ||
cy.get(".process-car") | ||
.each(v => { | ||
if (v.find(".forward-icon").length > largestCount) { | ||
largestCount = v.find(".forward-icon").length; | ||
} | ||
}) | ||
.then(() => { | ||
cy.get(".process-car").each(v => { | ||
if (v.find(".forward-icon").length === largestCount) { | ||
const winner = v.find(".car-player")[0].outerText; | ||
cy.get("#result-winner").contains(winner); | ||
} | ||
}); | ||
}); | ||
}); | ||
|
||
it("다시 시작하기 버튼을 클릭하면 자동차 섹션만 보이고, 입력 값이 초기화된다", () => { | ||
cy.get("#reset-btn").click(); | ||
cy.get("#count").should("have.css", "display", "none"); | ||
cy.get("#process").should("have.css", "display", "none"); | ||
cy.get("#result").should("have.css", "display", "none"); | ||
cy.get("#process").children().should("not.exist"); | ||
cy.get("#car-input").should("have.value", ""); | ||
}); | ||
}); | ||
|
||
describe("ui-input-vaild-check", () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 입력 테스트 (비즈니스), 레이아웃 테스트를 나눈 것은 아주 센스있는 코딩인 것 같습니다 😄 👍 👍 |
||
beforeEach(() => { | ||
cy.visit("http://localhost:5500/"); | ||
cy.window() | ||
.then(win => cy.stub(win, "alert")) | ||
.as("alertStub"); | ||
}); | ||
|
||
it("자동차 이름이 5글자 초과하면 alert 출력", () => { | ||
cy.get("#car-input").type("overFive,a,b,c,d"); | ||
cy.get("#car-btn").click(); | ||
cy.get("@alertStub").should( | ||
"be.calledWith", | ||
"자동차 이름의 길이는 최대 5글자 입니다." | ||
); | ||
}); | ||
|
||
it("자동차 이름에 공백 있으면 alert 출력", () => { | ||
cy.get("#car-input").type("a,b,,c,d"); | ||
cy.get("#car-btn").click(); | ||
cy.get("@alertStub").should( | ||
"be.calledWith", | ||
"자동차 이름은 공백이 될 수 없습니다." | ||
); | ||
}); | ||
|
||
it("자동차 이름에 중복 있으면 alert 출력", () => { | ||
cy.get("#car-input").type("a,b,a,c,d"); | ||
cy.get("#car-btn").click(); | ||
cy.get("@alertStub").should( | ||
"be.calledWith", | ||
"자동차 이름은 중복이 될 수 없습니다." | ||
); | ||
}); | ||
|
||
it("입력한 시도 횟수가 공백이면 alert 출력", () => { | ||
cy.get("#car-input").type("a,b,c,d"); | ||
cy.get("#car-btn").click(); | ||
cy.get("#count").should("have.css", "display", "block"); | ||
cy.get("#count-btn").click(); | ||
cy.get("@alertStub").should( | ||
"be.calledWith", | ||
"시도 횟수는 공백 혹은 문자가 될 수 없습니다." | ||
); | ||
}); | ||
|
||
it("입력한 시도 횟수가 0 이하면 alert 출력", () => { | ||
cy.get("#car-input").type("a,b,c,d"); | ||
cy.get("#car-btn").click(); | ||
cy.get("#count").should("have.css", "display", "block"); | ||
cy.get("#count-input").type(-1); | ||
cy.get("#count-btn").click(); | ||
cy.get("@alertStub").should( | ||
"be.calledWith", | ||
"시도 횟수는 0보다 작거나 같을 수 없습니다." | ||
); | ||
}); | ||
|
||
it("입력한 시도 횟수가 소수면 alert 출력", () => { | ||
cy.get("#car-input").type("a,b,c,d"); | ||
cy.get("#car-btn").click(); | ||
cy.get("#count").should("have.css", "display", "block"); | ||
cy.get("#count-input").type(4.21); | ||
cy.get("#count-btn").click(); | ||
cy.get("@alertStub").should( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Input -> btn -> should 와 같은 패턴이 많이 보이네요~ 이런 것도 함수로 제공하면 좋을 것 같습니다 :)
|
||
"be.calledWith", | ||
"시도 횟수는 소수가 될 수 없습니다." | ||
); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/// <reference types="cypress" /> | ||
// *********************************************************** | ||
// This example plugins/index.js can be used to load plugins | ||
// | ||
// You can change the location of this file or turn off loading | ||
// the plugins file with the 'pluginsFile' configuration option. | ||
// | ||
// You can read more here: | ||
// https://on.cypress.io/plugins-guide | ||
// *********************************************************** | ||
|
||
// This function is called when a project is opened or re-opened (e.g. due to | ||
// the project's config changing) | ||
|
||
/** | ||
* @type {Cypress.PluginConfig} | ||
*/ | ||
module.exports = (on, config) => { | ||
// `on` is used to hook into various events Cypress emits | ||
// `config` is the resolved Cypress config | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// *********************************************** | ||
// This example commands.js shows you how to | ||
// create various custom commands and overwrite | ||
// existing commands. | ||
// | ||
// For more comprehensive examples of custom | ||
// commands please read more here: | ||
// https://on.cypress.io/custom-commands | ||
// *********************************************** | ||
// | ||
// | ||
// -- This is a parent command -- | ||
// Cypress.Commands.add("login", (email, password) => { ... }) | ||
// | ||
// | ||
// -- This is a child command -- | ||
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) | ||
// | ||
// | ||
// -- This is a dual command -- | ||
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) | ||
// | ||
// | ||
// -- This will overwrite an existing command -- | ||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// *********************************************************** | ||
// This example support/index.js is processed and | ||
// loaded automatically before your test files. | ||
// | ||
// This is a great place to put global configuration and | ||
// behavior that modifies Cypress. | ||
// | ||
// You can change the location of this file or turn off | ||
// automatically serving support files with the | ||
// 'supportFile' configuration option. | ||
// | ||
// You can read more here: | ||
// https://on.cypress.io/configuration | ||
// *********************************************************** | ||
|
||
// Import commands.js using ES2015 syntax: | ||
import './commands' | ||
|
||
// Alternatively you can use CommonJS syntax: | ||
// require('./commands') |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,60 +16,29 @@ <h1 class="text-center">🏎️ 자동차 경주 게임</h1> | |
예시) EAST, WEST, SOUTH, NORTH | ||
</p> | ||
</section> | ||
<section> | ||
<div class="d-flex"> | ||
<input type="text" class="w-100 mr-2" placeholder="자동차 이름" /> | ||
<button type="button" class="btn btn-cyan">확인</button> | ||
</div> | ||
</section> | ||
<section class="mt-5"> | ||
<p>시도할 횟수를 입력해주세요.</p> | ||
<section id="car"> | ||
<div class="d-flex"> | ||
<input type="number" class="w-100 mr-2" placeholder="시도 횟수" /> | ||
<button type="button" class="btn btn-cyan">확인</button> | ||
<input | ||
type="text" | ||
id="car-input" | ||
class="w-100 mr-2" | ||
placeholder="자동차 이름" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. input 태그의 다양한 속성들을 이용해 사용자의 입력에 대한 접근을 제한해보면 어떨까요? |
||
/> | ||
<button type="button" id="car-btn" class="btn btn-cyan"> | ||
확인 | ||
</button> | ||
</div> | ||
</section> | ||
<section id="count" class="mt-5"></section> | ||
</div> | ||
</div> | ||
<div class="d-flex justify-center mt-5"> | ||
<section class="mt-4"> | ||
<div class="d-flex"> | ||
<div> | ||
<div class="car-player mr-2">EAST</div> | ||
<div class="forward-icon mt-2">⬇️️</div> | ||
<div class="forward-icon mt-2">⬇️️</div> | ||
</div> | ||
<div> | ||
<div class="car-player mr-2">WEST</div> | ||
<div class="forward-icon mt-2">⬇️️</div> | ||
</div> | ||
<div> | ||
<div class="car-player mr-2">SOUTH</div> | ||
<div class="d-flex justify-center mt-4"> | ||
<div class="relative spinner-container"> | ||
<span class="material spinner"></span> | ||
</div> | ||
</div> | ||
</div> | ||
<div> | ||
<div class="car-player mr-2">NORTH</div> | ||
<div class="d-flex justify-center mt-4"> | ||
<div class="relative spinner-container"> | ||
<span class="material spinner"></span> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</section> | ||
<section id="process" class="mt-4"></section> | ||
</div> | ||
<div class="d-flex justify-center mt-5"> | ||
<section> | ||
<h2>🏆 최종 우승자: EAST, WEST 🏆</h2> | ||
<div class="d-flex justify-center"> | ||
<button type="button" class="btn btn-cyan">다시 시작하기</button> | ||
</div> | ||
</section> | ||
<section id="result"></section> | ||
</div> | ||
</div> | ||
<script type="module" src="src/js/index.js"></script> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"dependencies": { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cypress는 빌드에 연관있는 툴은 아니므로, --dev 옵션을 주어 devDependencies로 이관하는게 좋지 않을까요? |
||
"cypress": "^6.4.0" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
export const RANDOM = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 상수를 별도의 파일에 저장하는 기법은 아주 좋은 방법입니다 👍 👍 |
||
MAX_NUM: 9, | ||
MIN_NUM: 0, | ||
}; | ||
|
||
export const INIT = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. init 값도 여기서 조절할 수 있게 되니 좋아보이네요! |
||
CARS: [], | ||
FORWARD: 0, | ||
COUNT: 0, | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 클래스에 대한 init을 상수로 관리하는 건 상황에 따라 다르겠지만, |
||
|
||
export const GAME = { | ||
FORWARD_STANDARD_NUM: 4, | ||
GO_NUM: 1, | ||
STOP_NUM: 0, | ||
}; | ||
|
||
export const VALID = { | ||
CARNAME_MAX_LENGTH: 5, | ||
CARNAME_MIN_LENGTH: 1, | ||
COUNT_MIN_NUM: 1, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export const ERROR_MESSAGE = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 메시지도 별도로 저장하니 좋은 것 같습니다! 👍 👍 |
||
OVER_CARNAME_MAX_LENGTH: "자동차 이름의 길이는 최대 5글자 입니다.", | ||
BLANK_CARNAME: "자동차 이름은 공백이 될 수 없습니다.", | ||
DUPLICATE_CARNAME: "자동차 이름은 중복이 될 수 없습니다.", | ||
|
||
ZERO_OR_MINUS_COUNT: "시도 횟수는 0보다 작거나 같을 수 없습니다.", | ||
ISNAN_COUNT: "시도 횟수는 공백 혹은 문자가 될 수 없습니다.", | ||
FLOAT_COUNT: "시도 횟수는 소수가 될 수 없습니다.", | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#***-input
을 입력하고#***-btn
을 클릭하는 동작이 중복되는 것 같습니다 😄해당 일련된 동작을 제공하는 함수를 만들어보는 건 어떨까요?