Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions 2 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ build
.vscode/
.idea/
.python-version
.venv
.DS_Store
4 changes: 4 additions & 0 deletions 4 e2e-test/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
APP_NAME='e2e-test'
DEBUG_MODE = False
SEND_EVENTS = True
LOG_FORMAT='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
95 changes: 95 additions & 0 deletions 95 e2e-test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@

# Analytics Python CLI

This tool is created for the purpose of E2E Testing.

## Dependencies

| Module | Version |
|--|--|
| python | 3.9 |
| click | 8.1.8 |
| python-dotenv | 1.0.1 |
| python-dateutil | 2.8.2 |
| requests | 2.32.3 |
| PyJWT | 2.10.1 |
| backoff | 2.2.1 |

## Installation

1. Change the working directory
```bash
$ cd e2e-test
```
2. Create a virtual environment inside the working directory
```bash
$ python3 -m venv .venv
```
3. Enable the virtual environment
```bash
$ source .venv/bin/activate
```
4. Install dependencies
```bash
$ pip install -r requirements.txt
```
5. Install the script as a module
```bash
$ pip install --editable .
```

## Usage Examples with Sample Payloads

| Command Option | Type | Description | Required |
|--|--|--|--|
| --writeKey | String | Segment Write Key | Yes |
| --apiHost | String | Custom Host | No |
| --payload | JSON | Event Payload | Yes |

### Example: Passing Multiple Events as JSON Array

```bash
$ e2e-test:run --writeKey='YOUR_WRITE_KEY' --apiHost='' --payload='"[{\"anonymousId\":\"507f191e810c89729de960ea\",\"channel\":\"browser\",\"context\":{\"app\":\"ecommerce\"},\"integrations\":{\"All\":false,\"Mixpanel\":true,\"Salesforce\":true},\"messageId\":\"022ty90c-bbac-11e4-8dfc-aa07a5b093q8\",\"traits\":{\"name\":\"Clark Kent\",\"email\":\"clark@example.com\",\"plan\":\"premium\",\"logins\":5,\"address\":{\"street\":\"6th St\",\"city\":\"San Francisco\",\"state\":\"CA\",\"postalCode\":\"94103\",\"country\":\"USA\"}},\"type\":\"identify\",\"userId\":\"AiUGstSDIg\",\"version\":\"2.0\"},{\"messageId\":\"122bb9ui-bbac-11e4-8dfc-aa07z5b098ip\",\"userId\":\"AiUGstSDIg\",\"type\":\"track\",\"event\":\"Course Clicked\",\"context\":{\"page\":{\"path\":\"/academy/\",\"referrer\":\"\",\"search\":\"\",\"title\":\"Analytics Academy\",\"url\":\"https://segment.com/academy/\"}},\"integrations\":{},\"properties\":{\"title\":\"Intro to Analytics\"}}]"'
```

### Example: Passing Individual Events

#### 1. Identify

``` bash
$ e2e-test:run --writeKey='YOUR_WRITE_KEY' --payload='"{\"anonymousId\":\"507f191e810c89729de960ea\",\"channel\":\"browser\",\"context\":{\"app\":\"ecommerce\"},\"integrations\":{\"All\":false,\"Mixpanel\":true,\"Salesforce\":true},\"messageId\":\"022bb90c-bbac-11e4-8dfc-aa07a5b093q8\",\"traits\":{\"name\":\"Clark Kent\",\"email\":\"clark@example.com\",\"plan\":\"premium\",\"logins\":5,\"address\":{\"street\":\"6th St\",\"city\":\"San Francisco\",\"state\":\"CA\",\"postalCode\":\"94103\",\"country\":\"USA\"}},\"type\":\"identify\",\"userId\":\"97980cfea0062\",\"version\":\"2.0\"}"'
```

#### 2. Track

``` bash
$ e2e-test:run --writeKey='YOUR_WRITE_KEY' --payload='"{\"messageId\":\"122bb90c-bbac-11e4-8dfc-aa07z5b098ip\",\"userId\":\"AiUGstSDIg\",\"type\":\"track\",\"event\":\"Course Clicked\",\"context\":{\"page\":{\"path\":\"/academy/\",\"referrer\":\"\",\"search\":\"\",\"title\":\"Analytics Academy\",\"url\":\"https://segment.com/academy/\"}},\"integrations\":{},\"properties\":{\"title\":\"Intro to Analytics\"}}"'
```

#### 3. Page

``` bash
$ e2e-test:run --writeKey='YOUR_WRITE_KEY' --payload='"{\"anonymousId\":\"507f191e810c19729de860ea\",\"channel\":\"browser\",\"integrations\":{\"All\":true,\"Mixpanel\":false,\"Salesforce\":false},\"messageId\":\"022bb90c-bbac-11e8-8dfc-aa07a5b090ol\",\"name\":\"Home\",\"properties\":{\"title\":\"Welcome | Initech\",\"url\":\"http://www.example.com\"},\"type\":\"page\",\"userId\":\"97980cfea0067\"}"'
```

#### 4. Screen

``` bash
$ e2e-test:run --writeKey='YOUR_WRITE_KEY' --payload='"{\"anonymousId\":\"507f191e810c19729de860ea\",\"channel\":\"browser\",\"integrations\":{\"All\":true,\"Mixpanel\":false,\"Salesforce\":false},\"messageId\":\"022bb90c-bbac-11e8-8dfc-aa07a5b090ol\",\"name\":\"Registration\",\"properties\":{\"title\":\"Welcome | Initech\",\"url\":\"http://www.example.com\"},\"type\":\"Screen\",\"userId\":\"97980cfea0067\"}"'
```

#### 5. Alias

``` bash
$ e2e-test:run --writeKey='YOUR_WRITE_KEY' --payload='"{\"anonymousId\":\"507f191e810c19729de800ea\",\"channel\":\"browser\",\"integrations\":{\"All\":true,\"Mixpanel\":false,\"Salesforce\":false},\"messageId\":\"022bb90c-bbac-11e4-8dfc-aa07u5b093lk\",\"previousId\":\"12345-239239-239239-23923\",\"type\":\"alias\",\"userId\":\"507f191e81\",\"version\":\"1.9\"}"'
```

#### 6. Group

``` bash
% e2e-test:run --writeKey='YOUR_WRITE_KEY' --payload='"{\"anonymousId\":\"507f191e810c19729de800ea\",\"channel\":\"browser\",\"integrations\":{\"All\":true,\"Mixpanel\":false,\"Salesforce\":false},\"messageId\":\"022bb90c-bbac-11e4-8dfc-aa07u5b093lk\",\"previousId\":\"12345-239239-239239-23923\",\"type\":\"alias\",\"userId\":\"507f191e81\",\"version\":\"1.9\"}"'
```

## Configuration Options

A few configuration options are available in the ```.env``` file.
Empty file added 0 e2e-test/__init__.py
Empty file.
1 change: 1 addition & 0 deletions 1 e2e-test/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

6 changes: 6 additions & 0 deletions 6 e2e-test/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
click==8.1.8
python-dotenv==1.0.1
python-dateutil==2.8.2
requests==2.32.3
PyJWT==2.10.1
backoff==2.2.1
16 changes: 16 additions & 0 deletions 16 e2e-test/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from setuptools import setup, find_packages

setup(
name='e2e-test',
version='0.1.0',
packages=find_packages(),
include_package_data=True,
install_requires=[
'click', 'python-dotenv', 'python-dateutil', 'requests', 'PyJWT', 'backoff'
],
entry_points={
'console_scripts': [
'e2e-test:run = src.cli:run',
],
},
)
Empty file added 0 e2e-test/src/__init__.py
Empty file.
102 changes: 102 additions & 0 deletions 102 e2e-test/src/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import click
from dotenv import load_dotenv
import os
import sys
import logging
import json
from collections.abc import Iterable

load_dotenv()

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../../")))

import segment.analytics as analytics # noqa: E402 (ignore autopep8)


@click.command()
@click.option('--writeKey', type=str, help='Segment write key')
neelkanth-kaushik marked this conversation as resolved.
Show resolved Hide resolved
@click.option('--apiHost', type=str, help='Custom host')
@click.option('--payload', type=str, help='A JSON string that specifies the event payload.')
def run(writekey, payload, apihost=None):
analytics.write_key = writekey

if apihost is not None:
analytics.host = apihost # Set custom host

analytics.debug = os.getenv('DEBUG_MODE')
analytics.send = os.getenv('SEND_EVENTS')
logger = log_config()

try:
# Decode the JSON payload
decodedJson = json.loads(payload)
dataObject = json.loads(decodedJson)

# To ensure for loop do not raise exception when individual JSON is passed
# we are converting the payload to a List having a single Dictionary as its item

if not isinstance(dataObject, Iterable): # Check if dataObject is non-iterable
dataObject = [dataObject]
elif isinstance(dataObject, dict): # Check if dataObject is a dictionary
dataObject = [dataObject]

# Iterate over each item in the payload JSON
for data in dataObject:

specType = data.get('type') if data.get('type') is not None else None
messageId = data.get('messageId') if data.get('messageId') is not None else None
userId = data.get('userId') if data.get('userId') is not None else ''
eventName = data.get('event') if data.get('event') is not None else None
traits = data.get('traits') if data.get('traits') is not None else None
properties = data.get('properties') if data.get('properties') is not None else None
context = data.get('context') if data.get('context') is not None else None
integrations = data.get('integrations') if data.get('integrations') is not None else None
groupId = data.get('groupId') if data.get('groupId') is not None else None
pageOrScreenName = data.get('name') if data.get('name') is not None else None
pageOrScreenCategory = data.get('category') if data.get('category') is not None else None
timestamp = data.get('timestamp') if data.get('timestamp') is not None else None
anonymousId = data.get('anonymousId') if data.get('anonymousId') is not None else ''
previousId = data.get('previousId') if data.get('previousId') is not None else None

if specType == 'identify':
analytics.identify(userId, traits, context, timestamp, anonymousId, integrations, messageId)
elif specType == 'track':
analytics.track(userId, eventName, properties, context, timestamp, anonymousId, integrations, messageId)
elif specType == 'page':
analytics.page(userId, pageOrScreenCategory, pageOrScreenName, properties,
context, timestamp, anonymousId, integrations, messageId)
elif specType == 'screen':
analytics.screen(userId, pageOrScreenCategory, pageOrScreenName, properties,
context, timestamp, anonymousId, integrations, messageId)
elif specType == 'alias':
analytics.alias(previousId, userId, context, timestamp, integrations, messageId)
elif specType == 'group':
analytics.group(userId, groupId, traits, context, timestamp, anonymousId, integrations, messageId)
else:
raise Exception
except Exception as e:
logger.exception(e)
finally:
analytics.flush()


def log_config():
# Create a logger object
logger = logging.getLogger(os.getenv('APP_NAME'))
logger.setLevel(logging.DEBUG)

handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)

# Define the log message format
formatter = logging.Formatter(os.getenv('LOG_FORMAT'))
handler.setFormatter(formatter)

# Attach the handler to the logger
logger.addHandler(handler)

return logger


if __name__ == '__main__':
run()
Morty Proxy This is a proxified and sanitized view of the page, visit original site.