qa-automation-order-router v1.0.0
qa-automation-order-router
npx mochawesome-merge ./mochawesome-report/CITADEL/.json ./mochawesome-report/CITADEL/.json -o ./mochawesome-report/CITADEL/output.json
Directory Structure
lib/
- contains reusable code for tests
order/
- all code needed to build and run an order test casestrategy-builders/
- contains utility methods for building an order strategy (vertical, iron condor, etc)test-cases/
- builds listst ofTestCases
to be used in tests. ATestCase
instance has all the data needed to build an orderorder-builder.js
- Makes building an order at runtime very easy. All of its methods returnthis
, so you can chain calls to it. For example:new OrderBuilder().market().day().build()
. This file also includesOrderLegBuilder
andOptionLegBuilder
for building order legs.
service/
- Each file in here is responsible for making remote http requests to our microservices. They all utilizeTwHttpClient
to make the requests.instrument.js
- fetches instruments (futures, equities), option chains, future products, etc. Any requests toinstruments-api
should be in here.order.js
- makes http requests toorder-api
.quotes.js
- makes http requests tomarket-data-server
.
test/
- contains reusable code useful for running testsaccount-context.js
- represents a single account with a live session. Allows you to make http requsts using theservice/
classes. If you need to make http requests with multiple accounts, instantiate multipleAccountContext
with different credentials.global-setup.js
- this is a mocha "root hook plugin". It gets run before entire test suite. In parallel mode, this will be run before each test suite process (each test file is a test suite). Make sure you--require
it when you run your tests. See here for more info.instrument-context.js
- responsible for storing/caching all instrument data needed during test runs.shared-contexts.js
- loads all data needed for a test run. For example,loginEquitiesAccount
can be called in abefore()
block to load equities, option chains, and underlying quotes to be used in test cases. All the data will be stored ininstrumentContext
, which tests have access to thanks toglobal-setup.js
.shared-tests.js
- any repetitive code used in test runs can be put here.
util/
- utility classes and methodscredentials.js
- holds a username, password, and account number that is used byAccountContext
to login.enums.js
- a bunch of enum objectsoption-expiration.js
- utility methods for getting data from an option expirationquote.js
- utility methods for getting data from a quoteresponse.js
- utility methods and classes for handling http responses. Contains aResponseContainer
class which holds the response body, any response errors, and the raw axios response object.tw-session.js
- holds an auth token and a remember token which get populated whenaccountContext.login()
is called.TwHttpClient
holds a reference to aTwSession
so it can make requests to our back-end using thesession.token
.
tw-http-client.js
- makes axios http requests. Each service inservices/
has a reference to aTwHttpClient
instance that it uses to make http requests.TwHttpClient
automatically adds theAuthorization
header to each request using itsTwSession
instance.
Using the lib/
code
Here is an example of how you might find the lib/
code helpful:
Building a list of Vertical spread orders and submitting them
- Create an instance of
AccountContext
andlogin()
before() {
const credentials = new Credentials('myusername', 'mypassword', '5WT11111')
// this.instrumentContext is available to all tests. It is set in the `global-setup.js` root hook plugin
const accountContext = AccountContext.create(credentials)
// POST /sessions to get an auth token. Store the auth token in accountContext.session
await accountContext.login()
}
For convenience, we have a loginDefaultAccount
, loginEquitiesAccount
, and loginFuturesAccount
in shared-contexts.js
that does all this for you.
- Load equities, option chains, and underlying quote
const symbols = ["AAPL"]
const instrumentContext = InstrumentContext.create(accountContext.userSession)
await instrumentContext.loadEquitiesData(symbols)
await instrumentContext.loadQuotes(symbols)
For convenience, we have a loginAndFetchEquitiesData()
method in shared-context.js
that does all this for you (including login).
- Build some test cases for different orders you'd like to test
// Use the expiration date that is > 1 day from now
const DefaultExpirationOffsetDays = 1
// Spreads should be 10 strikes wide
const DefaultSpreadWidth = 10
// First order leg should be 1 strike OTM
const DefaultAtmOffset = 1
const testCases = [
new VerticalTestCase("AAPL", DefaultSpreadWidth, DefaultAtmOffset, DefaultExpirationOffsetDays, OptionType.Call, OrderQuantity.QtyOne, Direction.Long, OpenClose.Open, TimeInForce.Day, OrderType.Limit, OrderPrice.Fill, PriceEffect.Debit, OrderStatus.Routed),
new VerticalTestCase("AAPL", DefaultSpreadWidth, DefaultAtmOffset, DefaultExpirationOffsetDays, OptionType.Put, OrderQuantity.QtyOne, Direction.Long, OpenClose.Open, TimeInForce.Day, OrderType.Limit, OrderPrice.Fill, PriceEffect.Debit, OrderStatus.Routed),
]
For convenience, we have a VerticalFilledTestCases
array in lib/order/test-cases/vertical.js
that iterates over a bunch of different values (Put/Call, Day/GTC/GTD, Long/Short, Open/Close) and builds test cases.
- Build json needed to submit the order, submit the order, and verify its state
testCases.forEach((testCase) => {
it(`${testCase.description()} order`, async function () {
// testCase creates an `OrderBuilder`. `OrderBuilder.build()` returns valid json object
const orderJson = testCase.buildOrder(this.instrumentContext).build()
let responseContainer
try {
// POST /accounts/{accountNumber}/orders/dry-run to see if preflight passes
responseContainer = await accountContext.orderService.dryRun(orderJson, accountContext.accountNumber)
} catch (error) {
// Extract any useful info from the response and log it. Then re-throw the error so the test fails
console.log(error.message)
extractNestedErrors(error.response).printHumanReadable()
console.log("Account number: ", accountContext.accountNumber)
console.log("Request body: ", orderJson)
throw error
}
expect(responseContainer.errors.isEmpty).to.be(true)
})
})
For convenience, we have a verifyDryRunFromTestCase
method in shared-tests.js
that does all this for you.
Smoke Tests
To run the smoke tests: npm run smokeTest
You can find instructions on running the smoke tests in smoke-tests/README.md
.
2 years ago