running-tools

A collection of tools for runners and their coaches
git clone https://git.ashermorgan.net/running-tools/
Log | Files | Refs | README

workout-calculator.spec.js (8719B)


      1 import { test, expect } from '@playwright/test';
      2 
      3 test('Workout Calculator', async ({ page }) => {
      4   // Go to workout calculator
      5   await page.goto('/');
      6   await page.getByRole('button', { name: 'Workout Calculator' }).click();
      7   await expect(page).toHaveTitle('Workout Calculator - Running Tools');
      8 
      9   // Test standard workout results
     10   {
     11     // Enter input race (2 mi in 10:30)
     12     await page.getByLabel('Input race distance value').fill('2');
     13     await page.getByLabel('Input race distance unit').selectOption('Miles');
     14     await page.getByLabel('Input race duration hours').fill('0');
     15     await page.getByLabel('Input race duration minutes').fill('10');
     16     await page.getByLabel('Input race duration seconds').fill('30');
     17 
     18     // Assert workout splits are correct
     19     await expect(page.getByRole('row').nth(1)).toHaveText('400 m @ 1 mi' + '1:13.45');
     20     await expect(page.getByRole('row').nth(3)).toHaveText('1600 m @ 1:00:00' + '5:45.44');
     21     await expect(page.getByRole('row')).toHaveCount(5);
     22   }
     23 
     24   // Test different calculator options options
     25   {
     26     // Change prediction model
     27     await page.getByText('Advanced Options').click();
     28     await page.getByLabel('Prediction model').selectOption('Riegel\'s Model');
     29 
     30     // Assert workout splits are correct
     31     await expect(page.getByRole('row').nth(1)).toHaveText('400 m @ 1 mi' + '1:15.10');
     32     await expect(page.getByRole('row').nth(3)).toHaveText('1600 m @ 1:00:00' + '5:45.64');
     33     await expect(page.getByRole('row')).toHaveCount(5);
     34 
     35     // Change Riegel exponent
     36     await page.getByLabel('Riegel Exponent').fill('1.12');
     37 
     38     // Assert workout splits are correct
     39     await expect(page.getByRole('row').nth(1)).toHaveText('400 m @ 1 mi' + '1:12.04');
     40     await expect(page.getByRole('row').nth(3)).toHaveText('1600 m @ 1:00:00' + '6:17.47');
     41     await expect(page.getByRole('row')).toHaveCount(5);
     42   }
     43 
     44   // Test modified default target set
     45   {
     46     // Edit default target set
     47     await page.getByRole('button', { name: 'Edit target set' }).click();
     48     await page.getByLabel('Target set label').fill('Less-common Workout Targets');
     49     await expect(page.getByLabel('Custom target name')).toHaveCount(0);
     50     await page.getByLabel('Split distance value').nth(0).fill('401');
     51     await page.getByLabel('Target distance value').nth(0).fill('2');
     52     await page.getByRole('button', { name: 'Add distance target' }).click();
     53     await page.getByLabel('Split distance value').last().fill('1');
     54     await page.getByLabel('Split distance unit').last().selectOption('Miles');
     55     await page.getByLabel('Target distance value').last().fill('10');
     56     await page.getByLabel('Target distance unit').last().selectOption('Kilometers');
     57     await page.getByRole('button', { name: 'Add time target' }).click();
     58     await page.getByLabel('Split distance value').last().fill('600');
     59     await page.getByLabel('Split distance unit').last().selectOption('Meters');
     60     await page.getByLabel('Target duration minutes').last().fill('19');
     61     await page.getByLabel('Target duration seconds').last().fill('0');
     62     await page.getByRole('button', { name: 'Add distance target' }).click();
     63     await page.getByLabel('Split distance value').last().fill('2');
     64     await page.getByLabel('Split distance unit').last().selectOption('Miles');
     65     await page.getByLabel('Target distance value').last().fill('2');
     66     await page.getByLabel('Target distance unit').last().selectOption('Miles');
     67     await page.getByRole('button', { name: 'Close' }).click();
     68 
     69     // Assert workout splits are correct
     70     await expect(page.getByRole('row').nth(1)).toHaveText('401 m @ 2 mi' + '1:18.49');
     71     await expect(page.getByRole('row').nth(2)).toHaveText('600 m @ 19:00' + '2:05.14');
     72     await expect(page.getByRole('row').nth(4)).toHaveText('1 mi @ 10 km' + '6:00.90');
     73     await expect(page.getByRole('row').nth(7)).toHaveText('2 mi' + '10:30.00');
     74     await expect(page.getByRole('row')).toHaveCount(8);
     75   }
     76 
     77   // Test custom target set (with custom target names)
     78   {
     79     // Enable target name customization
     80     await page.getByLabel('Workout name customization').selectOption('Enabled');
     81 
     82     // Create custom target set
     83     await page.getByLabel('Selected target set').selectOption('[ Create New Target Set ]');
     84     await expect(page.getByRole('row').nth(4)).toHaveText('There aren\'t any targets in this set yet.');
     85     await expect(page.getByRole('row')).toHaveCount(5);
     86 
     87     // Edit new target set
     88     await expect(page.getByRole('row').nth(1)).toHaveText('There aren\'t any targets in this set yet.');
     89     await expect(page.getByLabel('Target set label')).toHaveValue('New target set');
     90     await page.getByLabel('Target set label').fill('Workout Target Set #2');
     91     await page.getByRole('button', { name: 'Add distance target' }).click();
     92     await page.getByLabel('Custom target name').last().fill('800m Interval');
     93     await page.getByLabel('Split distance value').last().fill('800');
     94     await page.getByLabel('Split distance unit').last().selectOption('Meters');
     95     await page.getByLabel('Target distance value').last().fill('5');
     96     await page.getByLabel('Target distance unit').last().selectOption('Kilometers');
     97     await page.getByRole('button', { name: 'Add distance target' }).click();
     98     await page.getByLabel('Split distance value').last().fill('1600');
     99     await page.getByLabel('Split distance unit').last().selectOption('Meters');
    100     await page.getByLabel('Target distance value').last().fill('10');
    101     await page.getByLabel('Target distance unit').last().selectOption('Kilometers');
    102     await page.getByRole('button', { name: 'Close' }).click();
    103 
    104     // Assert workout splits are correct
    105     await expect(page.getByRole('row').nth(1)).toHaveText('800m Interval' + '2:45.08');
    106     await expect(page.getByRole('row').nth(2)).toHaveText('1600 m @ 10 km' + '5:58.81');
    107     await expect(page.getByRole('row')).toHaveCount(3);
    108   }
    109 
    110   // Reload page
    111   await page.reload();
    112 
    113   // Assert outputs are still the same
    114   {
    115     // Assert workout splits are correct (custom targets and model settings not reset)
    116     await expect(page.getByRole('row').nth(1)).toHaveText('800m Interval' + '2:45.08');
    117     await expect(page.getByRole('row').nth(2)).toHaveText('1600 m @ 10 km' + '5:58.81');
    118     await expect(page.getByRole('row')).toHaveCount(3);
    119 
    120     // Switch target set
    121     await page.getByText('Advanced Options').click();
    122     await page.getByLabel('Selected target set').selectOption('Less-common Workout Targets');
    123 
    124     // Assert workout splits are correct
    125     await expect(page.getByRole('row').nth(1)).toHaveText('401 m @ 2 mi' + '1:18.49');
    126     await expect(page.getByRole('row').nth(2)).toHaveText('600 m @ 19:00' + '2:05.14');
    127     await expect(page.getByRole('row').nth(4)).toHaveText('1 mi @ 10 km' + '6:00.90');
    128     await expect(page.getByRole('row').nth(7)).toHaveText('2 mi' + '10:30.00');
    129     await expect(page.getByRole('row')).toHaveCount(8);
    130   }
    131 
    132   // Test target set deletion and reversion
    133   {
    134     // Delete custom target set
    135     await page.getByLabel('Selected target set').selectOption('Workout Target Set #2');
    136     await page.getByRole('button', { name: 'Edit target set' }).click();
    137     await expect(page.getByLabel('Target set label')).toHaveValue('Workout Target Set #2');
    138     await page.getByRole('button', { name: 'Delete target set' }).click();
    139 
    140     // Switch to default target set
    141     await page.getByLabel('Selected target set').selectOption('Less-common Workout Targets');
    142 
    143     // Assert workout splits are correct (back to default target set)
    144     await expect(page.getByRole('row').nth(1)).toHaveText('401 m @ 2 mi' + '1:18.49');
    145     await expect(page.getByRole('row').nth(2)).toHaveText('600 m @ 19:00' + '2:05.14');
    146     await expect(page.getByRole('row').nth(4)).toHaveText('1 mi @ 10 km' + '6:00.90');
    147     await expect(page.getByRole('row').nth(7)).toHaveText('2 mi' + '10:30.00');
    148     await expect(page.getByRole('row')).toHaveCount(8);
    149 
    150     // Revert target set
    151     await page.getByRole('button', { name: 'Edit target set' }).click();
    152     await expect(page.getByLabel('Target set label')).toHaveValue('Less-common Workout Targets');
    153     await page.getByRole('button', { name: 'Revert target set' }).click();
    154     await page.getByRole('button', { name: 'Close' }).click();
    155 
    156     // Assert paces are correct
    157     await expect(page.getByRole('row').nth(1)).toHaveText('400 m @ 1 mi' + '1:12.04');
    158     await expect(page.getByRole('row').nth(3)).toHaveText('1600 m @ 1:00:00' + '6:17.47');
    159     await expect(page.getByRole('row')).toHaveCount(5);
    160 
    161     // Assert title was reset
    162     await page.getByRole('button', { name: 'Edit target set' }).click();
    163     await expect(page.getByLabel('Target set label')).toHaveValue('Common Workout Targets');
    164   }
    165 });