| name | credit-cashout |
| description | EGM credit insertion and cashout flows. Use when inserting credits, handling zero-balance denom popup trigger, cashing out, confirming cashout, checking credit balance, or managing credit top-up between game cycles. Covers: CashInController, CashoutController, forced denom popup on zero balance, cashout confirmation, credit balance checks. stages: test-implementation, test-validation |
Credit Insertion & Cashout
When to Use
- Inserting credits before gameplay
- Handling the forced denom popup triggered by credit insertion at zero balance
- Cashing out credits
- Checking or asserting credit balance
- Topping up credits between game cycles during bet/denom iteration
Credit Insertion
Zero Balance + Multi-Denomination Config
EGM displays a forced denomination selection popup before entering Active Play Mode. The game blocks until the player selects a denomination via ButtonNames.DenomButtons.GetDenomButtonName(index).
await cashInController.PressAddCreditsButtonAsync();
Non-Zero Balance
Credits are added silently. No popup. Game remains in Active Play Mode.
After Cashout
Returns to zero balance. Next credit insertion triggers the denomination selection popup again.
Credit Top-Up During Iteration
When iterating bet/denom combinations, credits may run out mid-loop. Top up with a bounded poll:
private const int CreditTopUpPollIntervalMs = 500;
private const int CreditTopUpTimeoutMs = 10_000;
private async Task EnsureCreditsForSpinAsync()
{
var credits = await statusDatabaseFacade.GetCurrentAvailableCreditsAsync();
if (credits > 0)
{
return;
}
await cashInController.PressAddCreditsButtonAsync();
using var cts = CancellationTokenSource.CreateLinkedTokenSource(CancellationToken);
cts.CancelAfter(CreditTopUpTimeoutMs);
try
{
while (!cts.Token.IsCancellationRequested)
{
var balance = await statusDatabaseFacade.GetCurrentAvailableCreditsAsync();
if (balance > 0)
{
return;
}
await Task.Delay(CreditTopUpPollIntervalMs, cts.Token);
}
}
catch (OperationCanceledException)
{
Assert.Fail("Credits are still zero after top-up attempt");
}
}
Cashout Flow
CashoutController.PressCashoutButtonAsync() initiates cashout.
- If
ConfigurationStatusProvider.IsCashoutConfirmRequiredAsync() returns true, a confirmation step is needed: CashoutController.PressConfirmCashoutButtonAsync().
- After cashout completes, the credit balance returns to zero.
- The game may enter Attract mode if no further interaction occurs.
await cashoutController.PressCashoutButtonAsync();
if (await configStatusProvider.IsCashoutConfirmRequiredAsync())
{
await cashoutController.PressConfirmCashoutButtonAsync();
}
var zeroed = await WaitForConditionAsync(
async () => await statusDatabaseFacade.GetCurrentAvailableCreditsAsync() == 0,
timeoutMs: 10_000,
pollIntervalMs: 500);
Assert.That(zeroed, Is.True, "Credits did not reach zero after cashout");
Credit Balance Checks
- Current balance:
StatusDatabaseFacade.GetCurrentAvailableCreditsAsync() — returns long
- Total bet for current stake:
StatusDatabaseFacade.GetCurrentTotalBetCreditsAsync() — returns long