feat: Phase 3 - Testing & Automation Features

- Implemented ScenarioRunner with headless scenario execution
- Added YAML-based test scenario framework with validation expectations
- Added CLI command 'run-scenario' with --headless, --output, --junit-xml options
- Created 3 Pterodisbot test scenarios:
  * Basic Server Status Flow (slash_command, select_menu, button_click)
  * Admin Commands (refresh_embeds, purge_embeds with permissions)
  * Multi-Guild Isolation (independent server tracking per guild)
- Fixed content_contains validation logic
- Fixed component_type validation for action rows
- Added command field to ScenarioBot model
- Fixed content_contains validation handling
- All 19 tests passing
This commit is contained in:
k.eaven committed 2026-11-01 05:31:44 +00:00
1 parent 7608388e1a
commit 6fbd7fea79
13 files changed
+1195 -11

No files matched your search

+174
View File
@@ -0,0 +1,174 @@
# Pterodisbot - Admin Commands Test
name: "Pterodisbot - Admin Commands"
description: "Test /refresh_embeds and /purge_embeds with permissions"
# Guild setup
setup:
guilds:
- id: "100000000000000000"
name: "Test Guild"
owner_id: "444444444444444444"
channels:
- "100000000000000010"
- "100000000000000011"
- "100000000000000012"
roles:
- "200000000000000001"
channels:
- id: "100000000000000010"
guild_id: "100000000000000000"
name: "general"
type: 0
position: 0
- id: "100000000000000011"
guild_id: "100000000000000000"
name: "bot-commands"
type: 0
position: 1
- id: "100000000000000012"
guild_id: "100000000000000000"
name: "server-status"
type: 0
position: 2
roles:
- id: "200000000000000001"
guild_id: "100000000000000000"
name: "Game Server User"
color: 3447003
hoist: true
position: 1
permissions: "104324161"
managed: false
mentionable: true
users:
- id: "444444444444444444"
username: "TestBot"
discriminator: "0000"
bot: true
- id: "300000000000000001"
username: "AdminUser"
discriminator: "0001"
bot: false
guild_roles:
"100000000000000000":
- "200000000000000001"
- id: "300000000000000002"
username: "RegularUser"
discriminator: "0002"
bot: false
guild_roles:
"100000000000000000":
- "200000000000000001"
# Pre-create some embeds in channels
messages:
- id: "100000000000000100"
channel_id: "100000000000000010"
author_id: "444444444444444444"
content: "Server Status: Minecraft Server"
embeds:
- title: "Minecraft Server - Running"
color: 0x00ff00
components:
- type: 1
components:
- type: 2
custom_id: "start_button"
label: "Start"
style: 3
- type: 2
custom_id: "stop_button"
label: "Stop"
style: 4
- id: "100000000000000101"
channel_id: "100000000000000011"
author_id: "444444444444444444"
content: "Server Status: Valheim Server"
embeds:
- title: "Valheim Server - Running"
color: 0x00ff00
components:
- type: 1
components:
- type: 2
custom_id: "start_button"
label: "Start"
style: 3
- type: 2
custom_id: "stop_button"
label: "Stop"
style: 4
- id: "100000000000000102"
channel_id: "100000000000000012"
author_id: "444444444444444444"
content: "Server Status: CS2 Server"
embeds:
- title: "CS2 Server - Running"
color: 0x00ff00
components:
- type: 1
components:
- type: 2
custom_id: "start_button"
label: "Start"
style: 3
- type: 2
custom_id: "stop_button"
label: "Stop"
style: 4
bot:
id: "444444444444444444"
username: "TestBot"
discriminator: "0000"
token: "test_token_123"
command: "python main.py" # Example command to start the bot (commented out for testing)
# Test steps
steps:
# Test 1: Regular user tries /refresh_embeds (should fail)
- action: "slash_command"
command: "refresh_embeds"
user_id: "300000000000000002" # RegularUser
guild_id: "100000000000000000"
channel_id: "100000000000000010"
expect:
- type: 4
data:
content_contains: "administrator permissions"
# Test 2: Admin user runs /refresh_embeds (should succeed)
- action: "slash_command"
command: "refresh_embeds"
user_id: "300000000000000001" # AdminUser
guild_id: "100000000000000000"
channel_id: "100000000000000010"
expect:
- type: 4
data:
content_contains: "Refreshed all embeds"
# Test 3: Regular user tries /purge_embeds (should fail)
- action: "slash_command"
command: "purge_embeds"
user_id: "300000000000000002" # RegularUser
guild_id: "100000000000000000"
channel_id: "100000000000000010"
expect:
- type: 4
data:
content_contains: "administrator permissions"
# Test 4: Admin user runs /purge_embeds (should succeed)
- action: "slash_command"
command: "purge_embeds"
user_id: "300000000000000001" # AdminUser
guild_id: "100000000000000000"
channel_id: "100000000000000010"
expect:
- type: 4
data:
content_contains: "Purge Complete"
+107
View File
@@ -0,0 +1,107 @@
# Pterodisbot - Basic Server Status Flow
name: "Pterodisbot - Basic Server Status Flow"
description: "Test /server_status -> select server -> click buttons"
# Guild setup
setup:
guilds:
- id: "100000000000000000"
name: "Test Guild"
owner_id: "444444444444444444"
channels:
- "100000000000000010"
roles:
- "200000000000000001"
channels:
- id: "100000000000000010"
guild_id: "100000000000000000"
name: "general"
type: 0 # GUILD_TEXT
position: 0
topic: "General discussion and bot commands"
roles:
- id: "200000000000000001"
guild_id: "100000000000000000"
name: "Game Server User"
color: 3447003
hoist: true
position: 1
permissions: "104324161"
managed: false
mentionable: true
users:
- id: "444444444444444444"
username: "TestBot"
discriminator: "0000"
bot: true
- id: "300000000000000001"
username: "TestUser"
discriminator: "1234"
bot: false
guild_roles:
"100000000000000000":
- "200000000000000001"
bot:
id: "444444444444444444"
username: "TestBot"
discriminator: "0000"
token: "test_token_123"
# command: "python main.py" # Example command to start the bot (commented out for testing)
# Test steps
steps:
- action: "slash_command"
command: "server_status"
user_id: "300000000000000001"
guild_id: "100000000000000000"
channel_id: "100000000000000010"
expect:
- type: 4 # CHANNEL_MESSAGE_WITH_SOURCE
data:
components: true
component_type: 1 # ACTION_ROW
custom_id: "server_dropdown"
options_count: 3
- action: "select_menu"
custom_id: "server_dropdown"
values: ["server_1"]
user_id: "300000000000000001"
guild_id: "100000000000000000"
channel_id: "100000000000000010"
message_id: "msg_123"
expect:
- type: 4
data:
embeds: true
components: true
component_type: 1 # ACTION_ROW
button_count: 4
- action: "button_click"
custom_id: "start_button"
user_id: "300000000000000001"
guild_id: "100000000000000000"
channel_id: "100000000000000010"
message_id: "msg_123"
expect:
- type: 4
data:
content_contains: "starting"
- action: "button_click"
custom_id: "show_address_button"
user_id: "300000000000000001"
guild_id: "100000000000000000"
channel_id: "100000000000000010"
message_id: "msg_123"
expect:
- type: 4
data:
embeds: true
embed_title_contains: "Connection Info"
fields_contain: ["Address", "Port"]
+162
View File
@@ -0,0 +1,162 @@
# Pterodisbot - Multi-Guild Isolation Test
name: "Pterodisbot - Multi-Guild Isolation"
description: "Verify guilds track servers independently"
# Guild setup
setup:
guilds:
- id: "100000000000000000"
name: "Guild Alpha"
owner_id: "444444444444444444"
channels:
- "100000000000000010"
roles:
- "200000000000000001"
- id: "100000000000000001"
name: "Guild Beta"
owner_id: "444444444444444444"
channels:
- "100000000000000020"
roles:
- "200000000000000002"
channels:
- id: "100000000000000010"
guild_id: "100000000000000000"
name: "general"
type: 0
position: 0
- id: "100000000000000020"
guild_id: "100000000000000001"
name: "general"
type: 0
position: 0
roles:
- id: "200000000000000001"
guild_id: "100000000000000000"
name: "Game Server User"
color: 3447003
hoist: true
position: 1
permissions: "104324161"
managed: false
mentionable: true
- id: "200000000000000002"
guild_id: "100000000000000001"
name: "Game Server User"
color: 3447003
hoist: true
position: 1
permissions: "104324161"
managed: false
mentionable: true
users:
- id: "444444444444444444"
username: "TestBot"
discriminator: "0000"
bot: true
- id: "300000000000000001"
username: "UserAlpha"
discriminator: "0001"
bot: false
guild_roles:
"100000000000000000":
- "200000000000000001"
- id: "300000000000000002"
username: "UserBeta"
discriminator: "0002"
bot: false
guild_roles:
"100000000000000001":
- "200000000000000002"
bot:
id: "444444444444444444"
username: "TestBot"
discriminator: "0000"
token: "test_token_123"
command: "python main.py" # Example command to start the bot
# Test steps
steps:
# Test 1: User in Guild Alpha selects Server A
- action: "slash_command"
command: "server_status"
user_id: "300000000000000001"
guild_id: "100000000000000000"
channel_id: "100000000000000010"
expect:
- type: 4
data:
components: true
custom_id: "server_dropdown"
- action: "select_menu"
custom_id: "server_dropdown"
values: ["server_1"]
user_id: "300000000000000001"
guild_id: "100000000000000000"
channel_id: "100000000000000010"
message_id: "msg_alpha"
expect:
- type: 4
data:
embeds: true
components: true
# Test 2: User in Guild Beta selects same Server A
- action: "slash_command"
command: "server_status"
user_id: "300000000000000002"
guild_id: "100000000000000001"
channel_id: "100000000000000020"
expect:
- type: 4
data:
components: true
custom_id: "server_dropdown"
- action: "select_menu"
custom_id: "server_dropdown"
values: ["server_1"]
user_id: "300000000000000002"
guild_id: "100000000000000001"
channel_id: "100000000000000020"
message_id: "msg_beta"
expect:
- type: 4
data:
embeds: true
components: true
# Test 3: User Alpha stops server in Guild Alpha
- action: "button_click"
custom_id: "stop_button"
user_id: "300000000000000001"
guild_id: "100000000000000000"
channel_id: "100000000000000010"
message_id: "msg_alpha"
expect:
- type: 4
data:
content_contains: "stopping"
# Test 4: Verify Guild Alpha embed shows offline, Guild Beta stays running
- action: "wait"
duration: 1
# Test 5: User Beta clicks Show Address in Guild Beta (should still work)
- action: "button_click"
custom_id: "show_address_button"
user_id: "300000000000000002"
guild_id: "100000000000000001"
channel_id: "100000000000000020"
message_id: "msg_beta"
expect:
- type: 4
data:
embeds: true
embed_title_contains: "Connection Info"
fields_contain: ["Address", "Port"]