feat(game): 添加成都麻将打牌功能和E2E测试

- 添加discardPending状态控制丢弃牌操作
- 实现canDiscardTiles计算属性判断是否可以丢弃牌
- 新增handleRoomStateResponse函数处理房间状态响应
- 实现discardTile函数发送丢弃牌消息
- 在游戏页面添加手牌操作栏显示可丢弃的牌
- 为定缺按钮和准备按钮添加data-testid标识
- 在大厅页面为房间操作元素添加data-testid标识
- 添加手牌操作相关的CSS样式
- 配置Playwright E2E测试框架
- 创建房间流程到打牌的完整E2E测试用例
This commit is contained in:
2026-03-29 16:47:56 +08:00
parent 4f7a54cf08
commit 5c9c2a180d
6 changed files with 681 additions and 6 deletions

View File

@@ -449,6 +449,7 @@ onMounted(async () => {
</div>
<button
class="primary-btn"
:data-testid="`room-enter-${room.room_id}`"
type="button"
:disabled="roomSubmitting"
@click="handleJoinRoom({ roomId: room.room_id, roomName: room.name })"
@@ -459,7 +460,7 @@ onMounted(async () => {
</ul>
<div class="room-actions-footer">
<button class="primary-btn wide-btn" type="button" @click="openCreateModal">创建房间</button>
<button class="primary-btn wide-btn" data-testid="open-create-room" type="button" @click="openCreateModal">创建房间</button>
<button class="ghost-btn wide-btn" type="button" @click="logoutToLogin">退出大厅</button>
</div>
</article>
@@ -471,8 +472,8 @@ onMounted(async () => {
<h3>快速加入</h3>
<form class="join-line" @submit.prevent="handleJoinRoom()">
<input v-model.trim="quickJoinRoomId" type="text" placeholder="输入 room_id" />
<button class="primary-btn" type="submit" :disabled="roomSubmitting">加入</button>
<input v-model.trim="quickJoinRoomId" data-testid="quick-join-room-id" type="text" placeholder="输入 room_id" />
<button class="primary-btn" data-testid="quick-join-submit" type="submit" :disabled="roomSubmitting">加入</button>
</form>
</aside>
</section>
@@ -486,7 +487,7 @@ onMounted(async () => {
<form class="form" @submit.prevent="submitCreateRoom">
<label class="field">
<span>房间名</span>
<input v-model.trim="createRoomForm.name" type="text" maxlength="24" placeholder="例如test001" />
<input v-model.trim="createRoomForm.name" data-testid="create-room-name" type="text" maxlength="24" placeholder="例如test001" />
</label>
<label class="field">
<span>玩法</span>
@@ -505,7 +506,7 @@ onMounted(async () => {
<div class="modal-actions">
<button class="ghost-btn" type="button" @click="closeCreateModal">取消</button>
<button class="primary-btn" type="submit" :disabled="roomSubmitting">
<button class="primary-btn" data-testid="submit-create-room" type="submit" :disabled="roomSubmitting">
{{ roomSubmitting ? '创建中...' : '创建' }}
</button>
</div>
@@ -528,7 +529,7 @@ onMounted(async () => {
</div>
<div class="modal-actions">
<button class="primary-btn" type="button" @click="enterCreatedRoom">进入房间</button>
<button class="primary-btn" data-testid="enter-created-room" type="button" @click="enterCreatedRoom">进入房间</button>
</div>
</section>
</div>