cswork / libraryOpen practice workspace

Articles

HackerEarth Full-Stack Assessment: Preview the App, Test Both Layers, and Submit

Prepare for a HackerEarth full-stack assessment with preview checks, API-to-UI debugging, a tested task-app contract, and Run Code versus Submit Code evidence.

A HackerEarth full-stack assessment can expose four different kinds of failure: the project never starts, the browser calls the wrong endpoint, one layer violates the required contract, or the candidate tests the code without saving a submission. A polished screen is useful evidence, but it does not establish that the backend stores the right data or that the platform received the solution.

This guide follows the documented provider workflow and an original task-app rehearsal. It does not predict an employer's time limit, passing score, permitted tools or exact project. Two independent candidate reports from the same hiring cycle were not established; no candidate anecdote is used as a process guarantee. Follow your invitation and supplied question when they define the rules.

Our local Python/SQLite app passed 15 HTTP checks and five real browser scenarios. Those results belong to the rehearsal, not HackerEarth's runner. Start with backend and React filter practice if you need to strengthen the complete request-to-screen path.

What should you establish before editing the project?

Official environment: HackerEarth's full-stack guide describes opening Edit in IDE, waiting for setup logs and using Question to read the prompt. Preview shows the frontend server in that documented environment. Startup readiness and application correctness remain separate checks.

Our preparation recommendation is to extract the observable contract before changing files. Identify the required screens, routes, payloads, ordering, validation, persistence and test commands. Read the existing project configuration to determine its actual framework and entry points. Replacing a supplied scaffold with a favorite stack creates additional integration assumptions without proving the requested behavior.

Record the baseline: which command starts each process, whether it completes, which URL opens, and what the initial tests report. A dependency installation still in progress is different from a server that exited. Keep the earliest relevant error and its command; the last line in a long log may only describe cleanup after the original failure.

Official example, scoped: The full-stack guide demonstrates a generated preview URL, a backend URL using a .backend suffix, and a frontend BASE_URL setting. Its example filenames and URL shape are clues, not instructions to invent paths for every project. Inspect the provided configuration and actual preview endpoints before changing them.

Make the smallest change that confirms the suspected boundary. If the frontend points at its own HTML server, changing a database query will not correct the request destination. If the endpoint receives the intended payload and rejects it correctly, changing the base URL is unlikely to solve a validation complaint.

How do you trace a working preview to the wrong API?

Our original app has one vertical slice: list tasks and create a task. GET /api/tasks returns JSON containing a tasks array in ascending ID order. POST to the same route accepts a JSON title, trims it, requires 1–60 characters afterward, and returns the stored task with a server-assigned integer ID. These are exercise requirements, not reported assessment specifications.

A deliberately wrong GET route, /wrong-api/tasks, returns the frontend HTML page with status 200. The preview still looks healthy. A client that checks only the status can mistake that response for API success and then fail while parsing the body.

Official browser behavior: MDN's Fetch reference explains that an HTTP error status does not by itself reject the fetch promise. Check status and response content before using the body. For this task contract, successful HTML is also the wrong representation.

Our original reader uses a compact guard for successful responses:

async function readSuccessfulTaskList(response) {
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  const type = response.headers.get('Content-Type') || '';
  if (!type.includes('application/json')) {
    throw new Error('Expected JSON from the task API');
  }
  const data = await response.json();
  if (!Array.isArray(data.tasks)) throw new Error('Missing tasks');
  return data.tasks;
}

This illustrates the boundary; the executed client also validates task IDs and titles and handles error messages. A valid JSON object is not necessarily a valid task list. Returning an error-shaped object with status 200 should not silently turn into an empty screen.

Trace method, final URL, request type, payload, status, response type and response shape. Then check whether that response reaches the intended rendering state. In our fixture, switching to the wrong route produces “Expected JSON; got HTML (HTTP 200)” while retaining the last valid list. Switching back restores a confirmed server read.

Which backend checks establish the required behavior?

Use a response-and-state ledger rather than counting green test lines. Each assertion should answer a requirement: accepted input, rejected input, stored output or unchanged state after failure.

Original requestExpected responseState or integration check
GET /api/tasks200 JSON tasks arrayIDs ordered; titles retain their values
GET /wrong-api/tasks200 HTMLReject as the wrong task representation
POST title with surrounding spaces201 JSON stored taskTrimmed title appears in a subsequent GET
POST blank, nonstring or 61-character title400 JSON errorNo task is added
POST malformed JSON400 JSON errorExisting list remains unchanged
POST raw text instead of required JSON415 JSON errorCorrect media type is part of this contract

Our HTTP checks exercised all those paths, the accepted 60-character boundary and an unknown route returning 404. Read-after-write confirmed that the accepted task was stored, not merely echoed by the handler. Invalid requests left the initial list unchanged before valid creates were performed.

The meaningful counterexample is a handler that returns 201 and the submitted title but never writes the row. A create-only assertion can pass; the following GET exposes the defect. Another is validation applied only in the browser: direct invalid requests bypass it. Backend rejection protects the contract regardless of which client constructs the request.

Use isolated fixture data and explicit assertions. A test that says “list length equals one” can fail because an earlier test created a legitimate row, while a test that merely checks “nonempty” can pass with the wrong data. Track the created ID and compare its stored title, or reset the local fixture using a deliberate procedure before a deterministic test run.

Our local checks do not establish concurrency safety, authentication, production resilience or hidden-test coverage. Add those only when the supplied requirements make them relevant, then explain the additional evidence needed. A small assessment feature still deserves a precise contract; it does not require an invented production architecture.

What must you test in the browser as well?

Our five browser scenarios covered invalid blank input, a successful create, persistence after page reload, the wrong-route HTML response and recovery after restoring the correct route. The visible list retained existing tasks after the invalid request and after the response-type error.

For the successful create, the screen displayed the server's task ID. Reloading the page retrieved that same task from the API. This checks a complete path through input, request, server state and rendering. Appending a local list item without checking the server would not provide equivalent evidence.

Error behavior also has a user contract. Preserve a correct list when a refresh fails, explain that the new read failed, and leave the user able to recover. Clearing all rows on a temporary response error can make “no tasks exist” indistinguishable from “tasks could not be loaded.” Our client retains the list and shows the failure instead.

Official boundary: MDN explains that cross-origin requests are subject to browser CORS behavior; an HTTP client succeeding is not proof that the browser can read its response. Using no-cors yields an opaque response and does not supply usable JSON. Our fixture is same-origin, so cross-origin deployment remains an additional check, not a claimed result.

If the project uses different frontend and backend origins, inspect the browser failure and supplied origin configuration before changing access rules. Separate a server rejection from a browser refusing to expose the response. Report the actual failed boundary, rather than rewriting the handler because one tool worked and another did not.

During implementation, define what a pending save means. Our client disables its Add task button while the request is pending; that avoids a common local duplicate click. It does not make the POST idempotent. If the server commits but the response is lost, blindly retrying can create another task. Discuss that ambiguity if retry behavior is required.

How do you manage mutable state and IDE recovery?

Treat source files, server processes, database rows and browser state as separate objects. A page reload replaces the browser view. It does not imply a database reset. A server restart and a restored assessment environment can have different effects, depending on the supplied project.

Our SQLite-backed fixture retained the created task across a browser reload while the server kept running. We did not claim that HackerEarth preserves database contents, or that our observation proves persistence across an IDE replacement. State the tested boundary exactly when explaining a result.

Official recovery: HackerEarth's VS Code guide says Facing IDE issues reloads the IDE while preserving written code. It does not establish a universal database-reset contract. Before using recovery, distinguish a lost connection from a reproducible application exception and preserve the error details you already have.

Official tools: The same guide documents project exploration, multiple terminals and EchoAPI for inspecting HTTP requests and responses. Use the provided capabilities within the assessment's instructions; their availability does not authorize external assistance or a particular AI workflow.

Our rehearsal recommendation is to keep an evidence note beside the code: last passing command, known failing input, stored fixture state and exact change under investigation. If you recover the environment, rerun the minimal baseline before making another code change. Otherwise, a restarted process or altered seed data can be mistaken for a fix.

How do Run Code and Submit Code differ?

Official submission distinction: In the documented VS Code workflow, Run Code executes sample tests and does not save a submission. Submit Code executes the hidden scored tests and saves a submission. Show last submission lets the candidate inspect previous submissions. A sample pass therefore does not establish either hidden-test success or submission receipt.

The following evidence matrix is our preparation aid. Its local rows describe checks you control; its platform rows apply to that documented workflow and must be reconciled with the actual assessment UI.

Evidence stateWhat it establishesWhat remains unproved
Preview opensFrontend can be viewedCorrect API, stored data, required behavior
API contract checks passTested requests and state match assertionsBrowser integration and untested boundaries
Browser path passesTested interaction reaches confirmed server stateComplete evaluator coverage
Run Code completesDocumented sample run was performedSaved submission and hidden-test result
Submission record is visibleA platform submission was recordedEmployer passing decision or final assessment completion

Before submitting, connect the current code to the last successful checks. A useful ledger includes the changed files, commands, outcomes and unresolved limitations. Do not leave a debug endpoint, hardcoded fixture result or altered test expectation in the solution simply because it made the preview green.

After the required submission action, inspect the available submission record and result rather than assuming the click succeeded. If you edit again, establish which version was submitted. Follow the assessment's completion instructions for the overall test; this guide does not invent a universal final button, retry policy or score guarantee.

Sources and Further Reading