Serial Peripheral Test Guide
A reference for the DeskTest.net Serial Peripheral Test. The browser cannot scan your machine for COM ports: the Web Serial API only opens the one port you explicitly pick in a native chooser. This guide covers what the tool opens, which baud rate to choose, how to read every verdict, and why a receipt printer that never answers is still a pass.
Open the Serial Peripheral Test →
What does the Serial Peripheral Test check?
The tool exercises the Web Serial API (navigator.serial) - the web platform's way to talk to a serial port straight from a browser tab. Three steps run in order:
- Support. Feature-detects
navigator.serialand confirms the page is a secure context. If either is missing, the run stops here. - Connect. You click Select a serial port. The browser calls
navigator.serial.requestPort()and shows its native picker. You choose your COM or USB-serial port; the tool callsport.open({ baudRate })at the baud rate you set, then reads the USB-serialvendorId/productIdback fromport.getInfo(). - Probe. The tool acquires the port's
writablestream to confirm bytes can be sent. If you left the box checked, it also writes a three-byte ESC/POS status request (DLE EOT) and reads for a moment to see whether the device answers.
The verdict centers on three things: the port opens, the baud rate negotiates, and the port is writable. A status reply is a bonus. Nothing leaves the workstation.
Serial vs the USB Device Test
DeskTest.net has two device tools that sound similar but use completely different transports. Pick by how the device presents itself:
| Use the Serial Peripheral Test when... | Use the USB Device Test when... |
|---|---|
The device shows up as a COM port (Windows) or /dev/ttyUSB* / /dev/ttyACM* (Linux). | The device is a raw USB or HID device (barcode scanner as a keyboard, payment terminal, signature pad). |
| Receipt printers in serial mode, cash drawers driven over serial, pole / customer displays, serial scales. | Devices with no COM port that a vendor app claims through WebUSB or WebHID. |
API: Web Serial (navigator.serial). | API: WebUSB / WebHID (navigator.usb / navigator.hid). |
A USB-serial cable (FTDI, Prolific, CP210x, CH340) creates a COM port, so it belongs here - even though it is physically a USB device. If you are not sure, check Windows Device Manager: anything under Ports (COM & LPT) is a serial device and this is the right tool.
When should I run this?
- A receipt printer stopped printing. Confirm the port still opens and takes bytes before you decide it is the printer, the cable, or the POS software.
- Setting up a new lane or front desk. Verify the receipt printer, cash drawer, and pole display each open on their COM port at the expected baud rate before the POS vendor arrives.
- A cash drawer will not pop. Most drawers are wired through the receipt printer, but some connect over their own serial line. Confirm that line opens and is writable.
- Isolating "hardware or app?" If this tool opens the port and writes cleanly but the POS still fails, the port and cabling are good and the problem is in the application or its COM-port configuration.
- Onboarding a workstation. Run once per serial device, note the VID/PID and baud, and file the report with the asset record.
Choosing a baud rate
Serial devices only communicate if both ends agree on the baud rate. The dropdown offers the four rates you will meet at a front desk:
| Baud | Typical device |
|---|---|
9600 | The most common default for receipt printers, pole displays, and older serial gear. Start here. |
19200 | Many Epson TM and Star TSP receipt printers when moved off 9600. |
38400 | Some scales and mid-range printers. |
115200 | Faster modern printers and many USB-serial dev boards. |
If you do not know the rate, the device usually prints it on a self-test slip: power a receipt printer on while holding the FEED button and it prints its current serial settings. If the port opens but a status query never replies, try the next baud rate - a wrong rate still opens the port but produces garbage on the wire.
Reading the results
Each step renders a row with a status badge: Pending (gray), Running (yellow), Pass (green), Warn (yellow), or Fail (red). The connect step shows a card with what the port reported:
- USB Vendor ID / Product ID in hex and decimal, for a USB-serial adapter. The pair
vid:pididentifies the bridge chip - e.g.0x0403is FTDI,0x1A86is the CH340,0x10C4is Silicon Labs CP210x,0x067Bis Prolific. - Native COM: a legacy motherboard serial port (or a driver that does not surface USB IDs) returns an empty
getInfo(). The tool reports "Native COM (no USB descriptor)" - that is normal, not an error. - Baud rate: the rate the port was opened at.
The probe step tells you one of three good outcomes: writable, device replied (bytes flow both ways - the strongest result); writable, no reply (normal for a write-only device); or writable, query skipped (you unchecked the box). All three are a pass. Only a port that opens but cannot be written is a fail.
The verdict panel at the top summarizes the run with a likely cause and a recommended next step. Copy Diagnostic Report puts a plain-text report (user-agent, secure-context status, VID/PID, baud, per-step results, any reply bytes) on the clipboard for a ticket.
Common failures and fixes
Every failure path in the tool has a named diagnosis. Here they are in the order steps run.
not-supported: navigator.serial is missing
The page asked for navigator.serial and got nothing. This browser does not ship Web Serial.
- You are on Firefox, Safari, or a mobile browser. None implement Web Serial and there are no plans on the Firefox or Safari roadmap as of 2026.
- Switch to desktop Chrome, Edge, Opera, or another Chromium-based desktop browser and re-run. Web Serial is desktop-only; it is absent on Chrome for Android and iOS.
insecure-context: not a secure context
Web Serial is only exposed over HTTPS or localhost. If you self-host this tool over plain HTTP, navigator.serial will not appear. Open https://desktest.net/serial-test/ directly, or serve your copy over HTTPS.
user-cancel: no port selected
You clicked Select a serial port, the picker appeared, and you closed it without choosing - or you clicked Skip. This is inconclusive, not a device failure.
- Click Reset, run again, and pick your port before the dialog closes.
- If the picker is empty, the browser sees no serial ports. On Windows, open Device Manager and look under Ports (COM & LPT). No entry means the USB-serial driver (FTDI, Prolific, CP210x, CH340) is not installed - install it and replug.
- On Linux, add your user to the
dialoutgroup (sudo usermod -aG dialout $USER) and log back in, so the browser can open/dev/ttyUSB*and/dev/ttyACM*.
open-failed: port picked but would not open
You selected a port and port.open() threw. The port exists but the OS would not hand it over.
- Another app holds it. Windows gives one COM port to one application at a time. Close the POS software, the vendor print utility (Epson TM Utility, StarPRNT, Bixolon), and any serial terminal (PuTTY, Tera Term), then run again.
- Wrong baud rate. A mismatched rate can still fail on some adapters. Try the next rate in the dropdown.
- Stale port. Unplug and replug the USB-serial cable so the OS re-enumerates it, then re-run. On Windows the COM number can change after a reconnect - re-pick it in the chooser.
blocked: serial access blocked by policy
The browser threw a SecurityError or NotAllowedError when asked for a port. An enterprise policy or a site setting is blocking serial access.
- Chrome and Edge honor
DefaultSerialGuardSetting. If IT set it to block, no port opens. Ask whoever manages the GPO to allow this origin (see For IT admins). - Check
chrome://settings/content/serialPortsis not set to block. - If this page is embedded in an iframe, the framing page must send
Permissions-Policy: serial=(self)and allow it on that frame.
not-writable: opened but not writable
The port opened but its writable stream was missing or already locked, so no bytes could be sent.
- Click Reset (which closes any handle this page still holds) and run again.
- Unplug and replug the device to force a clean port, then re-run.
- If it keeps failing, suspect the cable or adapter - swap in a known-good USB-serial cable.
For IT admins
You can pre-authorize serial ports for a fleet so users never see the chooser. This is the right answer for a fixed receipt printer on a known workstation and origin.
Chrome and Edge support the policy SerialAllowUsbDevicesForUrls, which grants named USB-serial devices (by vendor and product ID) to a list of origins without a per-user click:
[
{
"devices": [{ "vendor_id": 1027, "product_id": 24577 }],
"urls": ["https://desktest.net", "https://pos.internal.example.com"]
}
]
The example pre-authorizes an FTDI adapter (vid 0x0403 = 1027, pid 0x6001 = 24577). Push it as a GPO under Computer Configuration, Administrative Templates, Google Chrome (or Microsoft Edge). Note that this policy covers USB-serial devices with a VID/PID; native motherboard COM ports have no USB identity and cannot be pre-authorized this way.
The default for everything else is set by DefaultSerialGuardSetting: 2 blocks all sites, 3 asks (the browser default). Setting it to 2 plus an allowlist is a workable lockdown stance for kiosks.
Safari and Firefox have no equivalent. Neither ships Web Serial and neither has a policy to enable it. If Safari or Firefox is your standard browser, this page fails step 1 with not-supported on every workstation - and a browser-based POS that needs Web Serial will not work there either.
Behind the scenes
The serial port chooser is drawn by the browser, not the page. The page calls navigator.serial.requestPort() and the browser renders the list; a page cannot read it, style it, or pre-select an entry. That user-gesture-and-consent boundary is what lets the API exist at all - the tool never opens a port without your click.
Once you pick a port, port.open({ baudRate }) configures the line and exposes two Web Streams: port.readable and port.writable. The tool acquires a writer to prove bytes can be sent, and (optionally) a reader to catch a reply. Both stream locks are released and port.close() is called when the test finishes or you click Reset, so the port is never left held.
The optional status query is ESC/POS DLE EOT n (bytes 10 04 01), the real-time status request defined by Epson's ESC/POS command set. It asks the printer to transmit one status byte; it does not print and does not open a cash drawer (a drawer kick is a different command, ESC p / DLE DC4, which this tool never sends). A printer in bidirectional mode answers with a status byte encoding drawer, feed, and error state; a write-only device ignores it, which is why the tool never treats silence as failure. Uncheck the box to skip the query entirely and only verify writability.
port.getInfo() returns { usbVendorId, usbProductId } for a USB-serial adapter and an empty object for a native COM port - the tool handles both. Authorized ports persist per-origin: a port you granted on desktest.net is not visible to your internal POS site without a separate grant, and users revoke grants at chrome://settings/content/serialPorts.
No vendor IDs, baud rates, or reply bytes leave the browser. Copy Diagnostic Report puts the data on your clipboard for you to paste into a ticket.
Related
- Serial Peripheral Test - the diagnostic itself
- USB Device Test Guide - for raw USB / HID devices with no COM port
- Printer Test Guide - for printers reached through the OS print queue rather than a serial port
- Scanner Test Guide - for TWAIN / document scanners
- About DeskTest.net
- DeskTest.net home
Elsewhere on the web:
- Chrome Serial Terminal - open a COM port in the browser and type raw commands to a receipt printer, pole display, or scale.
- MDN: Web Serial API - the reference for
navigator.serial,requestPort, and the readable/writable streams.