Skip to content

Commit

Permalink
Merge pull request dmdorman#1647 from aeauseth/main
Browse files Browse the repository at this point in the history
End to end testing for AID
  • Loading branch information
aeauseth authored Dec 22, 2024
2 parents 1767634 + 0e16c08 commit 7aff673
Show file tree
Hide file tree
Showing 5 changed files with 299 additions and 39 deletions.
1 change: 1 addition & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export default [
OutlineOverlayFilter: "readonly",
DocumentSheetConfig: "readonly",
ActiveEffectConfig: "readonly",
Scene: "readonly",
},
},
},
Expand Down
4 changes: 4 additions & 0 deletions module/herosystem6e.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import "./utility/chat-dice.mjs";
import "./testing/testing-main.mjs";
import { EffectsPanel } from "./effects-panel.mjs";
import { HeroSystemActiveEffectConfig } from "./actor/active-effect-config.mjs";
import { HeroSystem6eEndToEndTest } from "./testing/end-to-end.mjs";

Hooks.once("init", async function () {
// Custom HeroSystem VisionMode
Expand Down Expand Up @@ -457,6 +458,9 @@ Hooks.once("ready", async function () {
// Update lastMigration
await game.settings.set(game.system.id, "lastMigration", game.system.version.replace("-alpha", ""));
}

// Testing
window.HeroSystem6eEndToEndTest = new HeroSystem6eEndToEndTest();
});

// New Actor Dialog
Expand Down
247 changes: 247 additions & 0 deletions module/testing/end-to-end.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
import { HeroSystem6eItem } from "../item/item.mjs";

export class HeroSystem6eEndToEndTest {
sceneName = "EndToEndTest";
//scene;
actor5Name = "_EndToEndTest5";
actor6Name = "_EndToEndTest6";
// actor5;
// actor6;
// orderedListElement;

delay = (ms) => new Promise((res) => setTimeout(res, ms || 100));

async start() {
await new Dialog({
title: `End To End Testing`,
content: `<div style="height:400px; overflow-y:scroll"><ol class="end-to-end-testing">
<li>Init</li>
</ol></div>`,
buttons: {
ok: {
label: "OK",
},
},
}).render(true);

for (let i = 0; i < 50; i++) {
if ((this.orderedListElement = $(".dialog .end-to-end-testing")).length > 0) break;
await this.delay();
}
this.orderedListElement.closest(".dialog").addClass("end-to-end-testing");
//$(".dialog.end-to-end-testing").css("left", 5);

await this.performTests();
}

async performTests() {
await this.createTestScene();
await this.createTestActors();
await this.testAid(this.token6);
await this.testAid(this.token5);
}

log(text, css) {
console.log(text);
this.orderedListElement.append(`<li style="${css}">${text}</li>`);
}

async createTestScene() {
this.scene = game.scenes.find((s) => s.name === this.sceneName);
if (this.scene) {
this.log(`Deleting Scene '${this.sceneName}'`);
this.scene.delete();
}
this.scene = await Scene.create({
name: "EndToEndTest",
width: 1000,
height: 500,
});
this.log(`Created scene: ${this.sceneName}`);

await this.scene.view();

// Remove all tokens
// for (const token of this.scene.tokens) {
// await token.delete();
// }
}

async createTestActors() {
// Scene Center
const x = Math.floor(this.scene.dimensions.width / 200) * 100;
const y = Math.floor(this.scene.dimensions.height / 200) * 100;

// 5e
for (const actor of game.actors.filter((a) => a.name === this.actor5Name)) {
this.log(`Deleting ${actor.name}`);
await actor.delete();
}
this.log(`Creating ${this.actor5Name}`);
this.actor5 = await Actor.create({
name: this.actor5Name,
type: "npc",
});
await this.actor5.update({ "system.is5e": true });
await TokenDocument.create(
{
name: this.actor5.name.replace("_", ""),
actorId: this.actor5.id,
x: x - 100,
y,
displayName: foundry.CONST.TOKEN_DISPLAY_MODES.ALWAYS,
},
{ parent: this.scene },
);
this.token5 = this.actor5.getActiveTokens()[0];

// 6e
for (const actor of game.actors.filter((a) => a.name === this.actor6Name)) {
this.log(`Deleting ${actor.name}`);
await actor.delete();
}
this.log(`Creating ${this.actor6Name}`);
this.actor6 = await Actor.create({
name: this.actor6Name,
type: "pc",
system: {
is5e: false,
},
});
await TokenDocument.create(
{
name: this.actor6.name.replace("_", ""),
actorId: this.actor6.id,
x: x + 100,
y,
displayName: foundry.CONST.TOKEN_DISPLAY_MODES.ALWAYS,
},
{ parent: this.scene },
);
this.token6 = this.actor6.getActiveTokens()[0];
}

async testAid(token) {
// Create AID
const xml = `
<POWER XMLID="AID" ID="1734814179562" BASECOST="0.0" LEVELS="2" ALIAS="Aid" POSITION="1" MULTIPLIER="1.0" GRAPHIC="Burst" COLOR="255 255 255" SFX="Default" SHOW_ACTIVE_COST="Yes" INCLUDE_NOTES_IN_PRINTOUT="Yes" NAME="" INPUT="STR" USESTANDARDEFFECT="No" QUANTITY="1" AFFECTS_PRIMARY="No" AFFECTS_TOTAL="Yes">
</POWER>
`;
const itemData = HeroSystem6eItem.itemDataFromXml(xml, token.actor);
const aidItem = await HeroSystem6eItem.create(itemData, { parent: token.actor });
await aidItem._postUpload();
this.log(`Added <b>${aidItem.name}</b> to <b>${aidItem.actor.name}</b>`);

// Target ourselves
await game.user.updateTokenTargets([token.id]);
// await game.user.broadcastActivity({
// targets: [this.token6.id],
// });

// Roll
await aidItem.roll();

// Wait for application to render then Click "Roll to Hit"
let button;
for (let i = 0; i < 50; i++) {
if ((button = $("#item-attack-form-application button")).length === 1) break;
await this.delay();
}
button.click();
this.log(`<b>${aidItem.name}</b> toHit`);

// Wait for chat chard then Roll AID
for (let i = 0; i < 50; i++) {
if (
(button = $(`ol#chat-log .chat-message:last-child button.roll-damage[data-item-id='${aidItem.uuid}']`))
.length === 1
)
break;
await this.delay();
}
button.click();
this.log(`Roll <b>${aidItem.name}</b>`);

// Wait for chat chard then Apply AID
for (let i = 0; i < 50; i++) {
if (
(button = $(
`ol#chat-log .chat-message:last-child button.apply-damage[data-item-id='${aidItem.uuid}']:last-child`,
)).length === 1
)
break;
await this.delay();
}
button.click();
this.log(`Apply <b>${aidItem.name}</b>`);

// Get AID Active Effect
let aidActiveEffect;
for (let i = 0; i < 50; i++) {
if ((aidActiveEffect = token.actor.temporaryEffects?.[0])) break;
await this.delay();
}
this.log(`Active Effect: ${aidActiveEffect.changes[0].key} ${aidActiveEffect.changes[0].value}`);

// Confirm STR has been aided
let aidValue = parseInt(aidActiveEffect.changes[0].value);
let actorStrValue = 10 + aidValue;
if (token.actor.system.characteristics.str.value !== actorStrValue) {
this.log(`FAIL`, "color:red");
return;
}

if (aidActiveEffect.changes.length !== 1) {
this.log(`FAIL: AE has more than 1 change`, "color:red");
return;
}

//const saveWorldTime = game.time.worldTime;

while (aidValue !== 0) {
// Advance world time 12 seconds

this.log(`worldTime + 12 seconds`);
await game.time.advance(12);

// Wait for AE to update/fade
for (let i = 0; i < 50; i++) {
if (token.actor.system.characteristics.str.value !== actorStrValue) break;
await this.delay();
}
aidActiveEffect = token.actor.temporaryEffects?.[0]; // Make sure we have latest updates

if (aidActiveEffect && aidActiveEffect.changes.length !== 1) {
this.log(`FAIL: AE has more than 1 change`, "color:red");
return;
}

// Check for fade
this.log(`Active Effect: ${aidActiveEffect?.changes[0].key} ${aidActiveEffect?.changes[0].value}`);
const aidNewValue = Math.max(0, aidValue - 5);
const actorNewStrValue = Math.max(10, actorStrValue - 5);
if (
(!aidActiveEffect && aidNewValue === 0) ||
token.actor.system.characteristics.str.value === actorNewStrValue
) {
this.log(`Fade from ${aidValue} to ${aidNewValue} was successful. STR=${actorNewStrValue}`);
} else {
this.log(
`Excpected actor STR=${actorNewStrValue} got ${token.actor.system.characteristics.str.value}`,
"color:red",
);
this.log(`Excpected change.value=${aidNewValue} got ${aidActiveEffect?.changes[0].value}`, "color:red");

// await this.delay();
// this.log(`Active Effect: ${aidActiveEffect.changes[0].key} ${aidActiveEffect.changes[0].value}`);

return;
}

// fade again?
aidValue = parseInt(aidActiveEffect?.changes[0].value || 0);
actorStrValue = 10 + aidValue;
}
this.log(`Active Effect: Fade completed succesfully`);
}
}
78 changes: 39 additions & 39 deletions module/utility/adjustment.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -236,23 +236,23 @@ function _createAEChangeBlock(targetCharOrPower, targetSystem) {
};
}

function _createAEChange(activeEffect, key, value, seconds, source, activePoints) {
activeEffect.changes ??= [];
activeEffect.changes.push({
key,
value,
mode: CONST.ACTIVE_EFFECT_MODES.ADD,
});
// activeEffect.flags ??= {};
// activeEffect.flags.changes ??= [];
// activeEffect.flags.changes.push({ seconds, source, activePoints, startTime: game.time.worldTime });

// Trying system approach
activeEffect.system ??= {};
activeEffect.system.changes ??= [];
activeEffect.system.changes.push({ seconds, source, activePoints, startTime: game.time.worldTime });
return activeEffect;
}
// function _createAEChange(activeEffect, key, value, seconds, source, activePoints) {
// activeEffect.changes ??= [];
// activeEffect.changes.push({
// key,
// value,
// mode: CONST.ACTIVE_EFFECT_MODES.ADD,
// });
// // activeEffect.flags ??= {};
// // activeEffect.flags.changes ??= [];
// // activeEffect.flags.changes.push({ seconds, source, activePoints, startTime: game.time.worldTime });

// // Trying system approach
// activeEffect.system ??= {};
// activeEffect.system.changes ??= [];
// activeEffect.system.changes.push({ seconds, source, activePoints, startTime: game.time.worldTime });
// return activeEffect;
// }

function _determineEffectDurationInSeconds(item, rawActivePointsDamage) {
let durationOptionId;
Expand Down Expand Up @@ -305,7 +305,7 @@ function _createNewAdjustmentEffect(
targetPower?.name || potentialCharacteristic // TODO: This will need to change for multiple effects
}`,
img: item.img,
//changes: [_createAEChangeBlock(potentialCharacteristic, targetSystem)],
changes: [_createAEChangeBlock(potentialCharacteristic, targetSystem)],
duration: {
seconds: _determineEffectDurationInSeconds(item, rawActivePointsDamage),
},
Expand Down Expand Up @@ -495,13 +495,13 @@ export async function performAdjustment(
}

// Update AE active points by summing changes
if (activeEffect.flags.changes) {
const _ap = activeEffect.flags.changes?.reduce((partialSum, a) => partialSum + (a.activePoints || 0), 0);
if (_ap !== 0 && activeEffect.flags.adjustmentActivePoints != _ap) {
console.log("New AP calc");
activeEffect.flags.adjustmentActivePoints = _ap;
}
}
// if (activeEffect.flags.changes) {
// const _ap = activeEffect.flags.changes?.reduce((partialSum, a) => partialSum + (a.activePoints || 0), 0);
// if (_ap !== 0 && activeEffect.flags.adjustmentActivePoints != _ap) {
// console.log("New AP calc");
// activeEffect.flags.adjustmentActivePoints = _ap;
// }
// }

// Healing is not cumulative but all else is. Healing cannot harm when lower than an existing effect.
let thisAttackEffectiveAdjustmentActivePoints = isHealing
Expand Down Expand Up @@ -595,20 +595,20 @@ export async function performAdjustment(

// Calculate the effect's change to the maximum. Only healing does not change the maximum.
if (!isOnlyToStartingValues) {
//activeEffect.changes[0].value = parseInt(activeEffect.changes[0].value) - totalActivePointAffectedDifference;
const _key =
targetSystem.system.characteristics?.[potentialCharacteristic.toLowerCase()] != null
? `system.characteristics.${potentialCharacteristic.toLowerCase()}.max`
: "system.max";
const _seconds = _determineEffectDurationInSeconds(item, thisAttackRawActivePointsDamage);
_createAEChange(
activeEffect,
_key,
-totalActivePointAffectedDifference,
_seconds,
item.uuid,
-totalAdjustmentNewActivePoints,
);
activeEffect.changes[0].value = parseInt(activeEffect.changes[0].value) - totalActivePointAffectedDifference;
// const _key =
// targetSystem.system.characteristics?.[potentialCharacteristic.toLowerCase()] != null
// ? `system.characteristics.${potentialCharacteristic.toLowerCase()}.max`
// : "system.max";
// const _seconds = _determineEffectDurationInSeconds(item, thisAttackRawActivePointsDamage);
// _createAEChange(
// activeEffect,
// _key,
// -totalActivePointAffectedDifference,
// _seconds,
// item.uuid,
// -totalAdjustmentNewActivePoints,
// );
}

// If this is 5e then some characteristics are calculated (not figured) based on
Expand Down
8 changes: 8 additions & 0 deletions scss/components/_junk.scss
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,11 @@ li.directory-item.child-item {
.characteristic-roll {
max-width: 40px;
}

// .dialog.end-to-end-testing {
// //background-color: rgba (255 0 0 /0.1);
// }

.dialog.end-to-end-testing .window-content {
background: rgba(255 255 255 80%);
}

0 comments on commit 7aff673

Please sign in to comment.