Skip to content

Commit

Permalink
Fullstory web API upgrade (segmentio#1869)
Browse files Browse the repository at this point in the history
* Fullstory web api upgrade

* adding more files

* PR feedback for FullStory Web API upgrade  (segmentio#1879)

* PR feedback

* documentation tweaks

---------

Co-authored-by: Scott Norvell <[email protected]>
  • Loading branch information
joe-ayoub-segment and ScottLNorvell authored Feb 19, 2024
1 parent aaf6d34 commit 3b0c7b0
Show file tree
Hide file tree
Showing 13 changed files with 767 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
},
"typings": "./dist/esm",
"dependencies": {
"@fullstory/browser": "^1.4.9",
"@fullstory/browser": "^2.0.3",
"@segment/actions-core": "^3.97.0",
"@segment/browser-destination-runtime": "^1.27.0"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,89 +1,49 @@
import { Analytics, Context } from '@segment/analytics-next'
import fullstory, { destination } from '..'
import fullstory from '..'
import trackEvent from '../trackEvent'
import identifyUser from '../identifyUser'
import viewedPage from '../viewedPage'
import { Subscription } from '@segment/browser-destination-runtime/types'
import { defaultValues } from '@segment/actions-core/*'

const FakeOrgId = 'asdf-qwer'

const example: Subscription[] = [
{
partnerAction: 'trackEvent',
name: 'Track Event',
enabled: true,
subscribe: 'type = "track"',
mapping: {
name: {
'@path': '$.name'
},
properties: {
'@path': '$.properties'
}
}
mapping: defaultValues(trackEvent.fields)
},
{
partnerAction: 'identifyUser',
name: 'Identify User',
enabled: true,
subscribe: 'type = "identify"',
mapping: {
anonymousId: {
'@path': '$.anonymousId'
},
userId: {
'@path': '$.userId'
},
email: {
'@path': '$.traits.email'
},
traits: {
'@path': '$.traits'
},
displayName: {
'@path': '$.traits.name'
}
}
mapping: defaultValues(identifyUser.fields)
},
{
partnerAction: 'viewedPage',
name: 'Viewed Page',
enabled: true,
subscribe: 'type = "page"',
mapping: defaultValues(viewedPage.fields)
}
]

test('can load fullstory', async () => {
const [event] = await fullstory({
orgId: 'thefullstory.com',
subscriptions: example
})

jest.spyOn(destination.actions.trackEvent, 'perform')
jest.spyOn(destination, 'initialize')

await event.load(Context.system(), {} as Analytics)
expect(destination.initialize).toHaveBeenCalled()

const ctx = await event.track?.(
new Context({
type: 'track',
properties: {
banana: '📞'
}
})
)

expect(destination.actions.trackEvent.perform).toHaveBeenCalled()
expect(ctx).not.toBeUndefined()

const scripts = window.document.querySelectorAll('script')
expect(scripts).toMatchInlineSnapshot(`
NodeList [
<script
crossorigin="anonymous"
src="https://edge.fullstory.com/s/fs.js"
/>,
<script>
// the emptiness
</script>,
]
`)
beforeEach(() => {
delete window._fs_initialized
if (window._fs_namespace) {
delete window[window._fs_namespace]
delete window._fs_namespace
}
})

describe('#track', () => {
it('sends record events to fullstory on "event"', async () => {
const [event] = await fullstory({
orgId: 'thefullstory.com',
orgId: FakeOrgId,
subscriptions: example
})

Expand All @@ -93,7 +53,7 @@ describe('#track', () => {
await event.track?.(
new Context({
type: 'track',
name: 'hello!',
event: 'hello!',
properties: {
banana: '📞'
}
Expand All @@ -112,16 +72,16 @@ describe('#track', () => {

describe('#identify', () => {
it('should default to anonymousId', async () => {
const [_, identifyUser] = await fullstory({
orgId: 'thefullstory.com',
const [_, identify] = await fullstory({
orgId: FakeOrgId,
subscriptions: example
})

await identifyUser.load(Context.system(), {} as Analytics)
await identify.load(Context.system(), {} as Analytics)
const fs = jest.spyOn(window.FS, 'setUserVars')
const fsId = jest.spyOn(window.FS, 'identify')

await identifyUser.identify?.(
await identify.identify?.(
new Context({
type: 'identify',
anonymousId: 'anon',
Expand All @@ -137,7 +97,7 @@ describe('#identify', () => {
}),
it('should send an id', async () => {
const [_, identifyUser] = await fullstory({
orgId: 'thefullstory.com',
orgId: FakeOrgId,
subscriptions: example
})
await identifyUser.load(Context.system(), {} as Analytics)
Expand All @@ -147,14 +107,14 @@ describe('#identify', () => {
expect(fsId).toHaveBeenCalledWith('id', {}, 'segment-browser-actions')
}),
it('should camelCase custom traits', async () => {
const [_, identifyUser] = await fullstory({
orgId: 'thefullstory.com',
const [_, identify] = await fullstory({
orgId: FakeOrgId,
subscriptions: example
})
await identifyUser.load(Context.system(), {} as Analytics)
await identify.load(Context.system(), {} as Analytics)
const fsId = jest.spyOn(window.FS, 'identify')

await identifyUser.identify?.(
await identify.identify?.(
new Context({
type: 'identify',
userId: 'id',
Expand All @@ -173,15 +133,15 @@ describe('#identify', () => {
})

it('can set user vars', async () => {
const [_, identifyUser] = await fullstory({
orgId: 'thefullstory.com',
const [_, identify] = await fullstory({
orgId: FakeOrgId,
subscriptions: example
})

await identifyUser.load(Context.system(), {} as Analytics)
await identify.load(Context.system(), {} as Analytics)
const fs = jest.spyOn(window.FS, 'setUserVars')

await identifyUser.identify?.(
await identify.identify?.(
new Context({
type: 'identify',
traits: {
Expand All @@ -204,15 +164,15 @@ describe('#identify', () => {
})

it('should set displayName correctly', async () => {
const [_, identifyUser] = await fullstory({
orgId: 'thefullstory.com',
const [_, identify] = await fullstory({
orgId: FakeOrgId,
subscriptions: example
})

await identifyUser.load(Context.system(), {} as Analytics)
await identify.load(Context.system(), {} as Analytics)
const fs = jest.spyOn(window.FS, 'identify')

await identifyUser.identify?.(
await identify.identify?.(
new Context({
type: 'identify',
userId: 'userId',
Expand All @@ -236,3 +196,93 @@ describe('#identify', () => {
)
})
})

describe('#page', () => {
it('sends page events to fullstory on "page" (category edition)', async () => {
const [, , viewed] = await fullstory({
orgId: FakeOrgId,
subscriptions: example
})

await viewed.load(Context.system(), {} as Analytics)
const fs = jest.spyOn(window.FS, 'setVars')

await viewed.page?.(
new Context({
type: 'page',
category: 'Walruses',
name: 'Walrus Page',
properties: {
banana: '📞'
}
})
)

expect(fs).toHaveBeenCalledWith(
'page',
{
pageName: 'Walruses',
banana: '📞'
},
'segment-browser-actions'
)
})

it('sends page events to fullstory on "page" (name edition)', async () => {
const [, , viewed] = await fullstory({
orgId: FakeOrgId,
subscriptions: example
})

await viewed.load(Context.system(), {} as Analytics)
const fs = jest.spyOn(window.FS, 'setVars')

await viewed.page?.(
new Context({
type: 'page',
name: 'Walrus Page',
properties: {
banana: '📞'
}
})
)

expect(fs).toHaveBeenCalledWith(
'page',
{
pageName: 'Walrus Page',
banana: '📞'
},
'segment-browser-actions'
)
})

it('sends page events to fullstory on "page" (no pageName edition)', async () => {
const [, , viewed] = await fullstory({
orgId: FakeOrgId,
subscriptions: example
})

await viewed.load(Context.system(), {} as Analytics)
const fs = jest.spyOn(window.FS, 'setVars')

await viewed.page?.(
new Context({
type: 'page',
properties: {
banana: '📞',
keys: '🗝🔑'
}
})
)

expect(fs).toHaveBeenCalledWith(
'page',
{
banana: '📞',
keys: '🗝🔑'
},
'segment-browser-actions'
)
})
})
Loading

0 comments on commit 3b0c7b0

Please sign in to comment.