Create an Employee

Site eaapp.somee.comTask create-employeeVersion v3Updated Aug 6, 2026Category browser-automation

Create a new employee through the authenticated EA App employee form, verify authentication, and report the server-side result. This skill was captured from a live agent session on eaapp.somee.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

Create an employee with supplied details in EA App and return whether the server accepted it as a non-duplicate employee. The skill also supports directly verifying whether an employee record is present by name.

When to Use

Use this skill when an authenticated profile must create or verify an employee on eaapp.somee.com. For creation, the caller supplies Name, Age, Salary, DurationWorked, Email, and optionally Grade. For verification-only requests, the caller supplies an employee name. Use made-up values only when the caller explicitly requests test data.

Workflow

  1. For verification-only, navigate directly to https://eaapp.somee.com/Employee?searchTerm={url-encoded-name} and run the extractor in step 5. Treat found: true as evidence that a matching row is listed, not as proof of a successful creation event.

  2. For creation, navigate directly to https://eaapp.somee.com/Employee/Create with the requested authenticated browser profile.

  3. In one page evaluation, first verify authentication, resolve the requested Grade label to its actual option value when supplied, fill the form using the native value setters, and submit with form.requestSubmit(). If navigation landed on /Account/Login or /Account/AccessDenied, report that the profile lacks the required authentication or authorization instead of submitting.

(() => {
  const auth = {
    url: location.href,
    loggedIn:
      !!document.querySelector(
        'form[action*="Logout" i], form[action*="LogOff" i]',
      ) || /Hello\s+[^!]+!/i.test(document.body?.innerText || ""),
  };
  if (/\/Account\/Login(?:[\/?#]|$)/i.test(location.pathname))
    return { ...auth, submitted: false, error: "Not logged in" };
  if (/\/Account\/AccessDenied(?:[\/?#]|$)/i.test(location.pathname))
    return { ...auth, submitted: false, error: "Access denied" };

  const values = {
    Name: "{name}",
    Age: "{age}",
    Salary: "{salary}",
    DurationWorked: "{duration-worked}",
    Grade: "{grade-or-empty-string}",
    Email: "{email}",
  };

  const nameControl = document.getElementById("Name");
  const form = nameControl?.form;
  if (!form) throw new Error("Create form not found (no #Name field on page)");

  const gradeControl = document.getElementById("Grade");
  if (!gradeControl) throw new Error("Grade control not found");
  const requestedGrade = String(values.Grade || "").trim();
  const gradeOption = requestedGrade
    ? Array.from(gradeControl.options).find(
        (o) =>
          o.value === requestedGrade ||
          o.textContent.trim().toLowerCase() === requestedGrade.toLowerCase(),
      )
    : Array.from(gradeControl.options).find((o) => o.value !== "");
  const gradeValue = gradeOption?.value;
  if (!gradeValue) throw new Error("No usable Grade option found");

  const inputSetter = Object.getOwnPropertyDescriptor(
    HTMLInputElement.prototype,
    "value",
  ).set;
  const selectSetter = Object.getOwnPropertyDescriptor(
    HTMLSelectElement.prototype,
    "value",
  ).set;
  for (const [id, value] of Object.entries({ ...values, Grade: gradeValue })) {
    const control = document.getElementById(id);
    if (!control || value == null || value === "")
      throw new Error(`Missing required control or value: ${id}`);
    (control.tagName === "SELECT" ? selectSetter : inputSetter).call(
      control,
      String(value),
    );
    for (const event of ["input", "change", "blur"])
      control.dispatchEvent(new Event(event, { bubbles: true }));
  }

  if (!form.checkValidity()) throw new Error("Form invalid after fill");
  const result = {
    ...auth,
    submitted: true,
    formAction: form.action,
    gradeRequested: requestedGrade || null,
    gradeUsed: gradeValue,
    gradeLabel: gradeOption.textContent.trim(),
    values: Object.fromEntries(
      Object.keys(values).map((id) => [id, document.getElementById(id).value]),
    ),
  };
  form.requestSubmit();
  return result;
})();
  1. Wait for navigation (waitForNavigation, ~15000 ms). A successful creation redirects to https://eaapp.somee.com/Employee with the session still authenticated. Landing back on /Employee/Create means validation failed—extract .field-validation-error / .validation-summary-errors text. Landing on the home page logged out means the wrong form was submitted.

  2. Verify the created name with one direct navigation to https://eaapp.somee.com/Employee?searchTerm={url-encoded-name}, then run this extractor and require found: true:

(() => {
  const query = new URLSearchParams(location.search).get("searchTerm") || "";
  const normalized = query.trim().toLowerCase();
  const rows = Array.from(document.querySelectorAll("table tbody tr")).map(
    (tr, index) => {
      const cells = Array.from(tr.querySelectorAll("th, td")).map((cell) =>
        cell.innerText.trim(),
      );
      return { index, cells, text: cells.join(" | ") };
    },
  );
  const matches = normalized
    ? rows.filter((row) => row.text.toLowerCase().includes(normalized))
    : [];
  return {
    url: location.href,
    title: document.title,
    query,
    totalRows: rows.length,
    found: matches.length > 0,
    matches,
  };
})();

Run verification while authenticated: the anonymous list view can render “No employees found” even when the record exists, so a logged-out search is not evidence of failed creation.

Site-Specific Gotchas

  • The navbar Logout form is the first <form> in document order on every authenticated page. Generic form selectors can submit /Account/Logout; always anchor form selection on #Name (document.getElementById('Name').form or form:has(#Name)).
  • The creation page is directly reachable at /Employee/Create; no homepage or employee-list interaction is required.
  • Unauthenticated requests redirect to /Account/Login?ReturnUrl=%2FEmployee%2FCreate. Check for that redirect or authenticated Hello ...! / Logout markers before submitting.
  • A profile may reach /Account/AccessDenied?ReturnUrl=%2FEmployee%2FCreate; creating employees requires the admin role. Do not attempt registration or credential creation as a workaround.
  • Form controls use IDs Name, Age, Salary, DurationWorked, Grade, and Email.
  • #DurationWorked is a number input that can silently drop values assigned by ordinary keystrokes; use native prototype setters and dispatch input, change, and blur.
  • Grade must not be empty. Observed option values are numeric (Junior=1, Middle=2, Senior=3, C-Level=4); resolve labels against option text and submit the matched value. If omitted, select the first nonempty option.
  • Submit with form.requestSubmit() on the #Name-anchored form so antiforgery tokens and cookies are included. Avoid real mouse clicks because ad overlays can intercept them and navigate to an ad page.
  • Employee lookup uses /Employee?searchTerm={url-encoded-name}. Results are table tbody tr; extract both th and td text rather than assuming a fixed column count.
  • The form selector and field IDs are stable in the observed page; re-check them if the site changes its markup.

Expected Output

For creation, return the pre-submit evaluation object (authentication status, formAction, requested and submitted Grade values, filled field values, and submitted) followed by post-navigation verification. Report success only when the search extractor returns found: true for the new employee while authenticated. For verification-only requests, return the search extractor object with query, totalRows, found, and matching row cell arrays. Report login or access-denied failures explicitly. Do not expose credentials or hidden form-token values.

Call it

GET https://production-sfo.browserless.io/skills?token=TOKEN-HERE&domain=eaapp.somee.com&task=create-employee