Audit 7shifts Time Clock Punches

Site app.7shifts.comTask audit-7shifts-time-clock-punchesVersion v4Updated Aug 20, 2026Category reporting

Open the 7shifts time-clock audit page, pass its Cloudflare challenge when presented, and extract rendered punch records and displayed audit metadata for a requested business date. This skill was captured from a live agent session on app.7shifts.com and publishes here verbatim, exactly as an agent receives it.

NoteSelectors and URL schemes drift as sites change. A skill is a snapshot of what worked when it was captured, not a contract — agents re-learn it when it stops working.

Purpose

Retrieve the rendered 7shifts time-clock punch audit for {date}, preserving punch rows, visible table structure, and page metadata in a structured result.

When to Use

Use for nightly or historical audits of employee clock-in, clock-out, and punch-adjustment records in 7shifts. The caller must have an authenticated 7shifts session and should provide the requested business date in MM/DD/YYYY form. Use the separate login-to-7shifts skill when authentication is required.

Workflow

  1. In one browser automation batch, navigate directly to https://app.7shifts.com/time_clocking_addon with a load timeout of about 40 seconds.
  2. Immediately invoke the browser's Cloudflare solver with a timeout of about 30 seconds if the challenge is present, then wait about 8–10 seconds for the client-rendered application to resume. Do not navigate to or retain transient Cloudflare challenge URLs.
  3. Run the following evaluate() on the loaded page. It extracts visible HTML tables when present, falls back to visible ARIA rows, captures date controls and audit metadata, and returns a bounded text fallback.
(() => {
const clean = value => String(value || '').replace(/\u00a0/g, ' ').replace(/\s+/g, ' ').trim();
const textOf = el => clean(el?.innerText || el?.textContent || '');
const visible = el => !!el && el.offsetParent !== null;
const visibleTables = [...document.querySelectorAll('table')].filter(visible);
const tables = visibleTables.map((table, index) => ({
index,
caption: textOf(table.querySelector('caption')),
headers: [...table.querySelectorAll('thead th')].map(textOf).filter(Boolean),
rows: [...table.querySelectorAll('tbody tr, tr')]
.map(row => [...row.querySelectorAll(':scope > th, :scope > td')].map(textOf))
.filter(row => row.some(Boolean))
})).filter(table => table.rows.length);
const ariaRows = tables.length ? [] : [...document.querySelectorAll('[role="row"]')]
.filter(visible)
.map(row => [...row.querySelectorAll(':scope > [role="cell"], :scope > [role="gridcell"], :scope > [role="columnheader"]')].map(textOf))
.filter(row => row.some(Boolean));
const controls = [...document.querySelectorAll('input, select, button')]
.filter(visible)
.map(el => ({
tag: el.tagName.toLowerCase(),
type: el.getAttribute('type') || '',
name: el.getAttribute('name') || '',
ariaLabel: el.getAttribute('aria-label') || '',
placeholder: el.getAttribute('placeholder') || '',
value: 'value' in el ? clean(el.value) : textOf(el)
}))
.filter(control => control.value || control.name || control.ariaLabel || control.placeholder);
const bodyText = textOf(document.body);
const displayedDate = bodyText.match(/(?:business date|audit date|date|for)\s*[:\-]?\s*([A-Za-z]{3,9}\s+\d{1,2},\s+\d{4}|\d{1,2}\/\d{1,2}\/\d{4}|\d{4}-\d{2}-\d{2})/i)?.[1] || '';
const error = bodyText.match(/sign in|log in|unauthorized|forbidden|error|unable to load|no data|session expired/i)?.[0] || '';
return {
url: location.href,
title: document.title,
path: location.pathname,
reportType: '7shifts time-clock punches',
displayedDate,
tableCount: tables.length,
tables,
ariaRows,
controls,
visibleText: bodyText.slice(0, 20000),
authOrError: error
};
})()
  1. Verify that the displayed audit date, when present, matches {date}. This route was observed without a stable date query parameter; do not fabricate or append date parameters. If the page is showing another date, use the page's own authenticated date control before rerunning the evaluator, and treat an unverified date as an incomplete audit.

Site-Specific Gotchas

  • The stable feature route observed for this audit is /time_clocking_addon, rather than a homepage navigation sequence.
  • 7shifts renders the time-clock content client-side; wait after Cloudflare resolution and navigation before extracting rows.
  • The route can present a Cloudflare challenge before the application becomes available. Use the browser Cloudflare solver and then wait for the app to render; do not reuse challenge URLs or challenge parameters.
  • No stable date query parameter was observed for this route. Never guess a date parameter or rely on the URL alone; verify the date displayed by the page or its date control.
  • Punch data may be rendered as ordinary HTML tables or ARIA grid rows. The evaluator handles both and preserves row cell boundaries.
  • If the page redirects to authentication, invoke login-to-7shifts and retry the direct route. Do not retain transient OAuth URLs or expose credentials.
  • An empty result, an authentication message, a displayed date different from {date}, or a page still showing a Cloudflare challenge is not a successful historical audit.

Expected Output

Return the evaluator object with the final URL, page title and path, displayed audit date, ordered punch tables or ARIA rows, visible date-control metadata, bounded fallback text, and any authentication, Cloudflare, or loading error indication.

Call it

GET https://production-sfo.browserless.io/skills?token=TOKEN-HERE&domain=app.7shifts.com&task=audit-7shifts-time-clock-punches