Skip to content

Commit

Permalink
Merge branch 'master' into hogql-button
Browse files Browse the repository at this point in the history
  • Loading branch information
mariusandra committed Oct 12, 2023
2 parents 87c0344 + b75813b commit 4a2ebe2
Show file tree
Hide file tree
Showing 245 changed files with 3,067 additions and 7,078 deletions.
8 changes: 0 additions & 8 deletions .github/ISSUE_TEMPLATE/sprint_planning_retro.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,6 @@ title: Sprint 1.n.0 m/2 - Jan 1 to Jan 12
2.
3.

## Retro: What can we do better next sprint?

1.
2.
3.
4.
5.


# Team sprint planning

Expand Down
12 changes: 10 additions & 2 deletions .github/workflows/ci-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ jobs:
# version changes
- docker-compose.dev.yml
- Dockerfile
- cypress/**
# Job that lists and chunks spec file names and caches node modules
chunks:
Expand Down Expand Up @@ -211,7 +212,10 @@ jobs:
- name: Wait for PostHog
# these are required checks so, we can't skip entire sections
if: needs.changes.outputs.shouldTriggerCypress == 'true'
uses: iFaxity/wait-on-action@v1
# this action might be abandoned - but v1 doesn't point to latest of v1 (which it should)
# so pointing to v1.1.0 to remove warnings about node version with v1
# todo check https://github.com/iFaxity/wait-on-action/releases for new releases
uses: iFaxity/[email protected]
timeout-minutes: 3
with:
verbose: true
Expand All @@ -221,12 +225,16 @@ jobs:
- name: Cypress run
# these are required checks so, we can't skip entire sections
if: needs.changes.outputs.shouldTriggerCypress == 'true'
uses: cypress-io/github-action@v5
uses: cypress-io/github-action@v6
with:
config-file: cypress.e2e.config.ts
config: retries=2
spec: ${{ matrix.chunk }}
install: false
env:
E2E_TESTING: 1
OPT_OUT_CAPTURE: 0
GITHUB_ACTION_RUN_URL: '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'

- name: Archive test screenshots
uses: actions/upload-artifact@v3
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/ci-plugin-server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ jobs:
fail-fast: false
matrix:
POE_EMBRACE_JOIN_FOR_TEAMS: ['', '*']
KAFKA_CONSUMPTION_USE_RDKAFKA: ['true', 'false']

env:
REDIS_URL: 'redis://localhost'
Expand All @@ -199,7 +198,6 @@ jobs:
KAFKA_HOSTS: 'kafka:9092'
DATABASE_URL: 'postgres://posthog:posthog@localhost:5432/posthog'
POE_EMBRACE_JOIN_FOR_TEAMS: ${{matrix.POE_EMBRACE_JOIN_FOR_TEAMS}}
KAFKA_CONSUMPTION_USE_RDKAFKA: ${{matrix.KAFKA_CONSUMPTION_USE_RDKAFKA}}

steps:
- name: Code check out
Expand Down
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"name": "Celery",
"type": "python",
"request": "launch",
"module": "celery",
"program": "${workspaceFolder}/env/bin/celery",
"console": "integratedTerminal",
"python": "${workspaceFolder}/env/bin/python",
"cwd": "${workspaceFolder}",
Expand Down
1 change: 1 addition & 0 deletions bin/docker-server
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ exec gunicorn posthog.wsgi \
--worker-tmp-dir /dev/shm \
--workers=2 \
--threads=8 \
--keep-alive=60 \
--backlog=${GUNICORN_BACKLOG:-1000} \
--worker-class=gthread \
${STATSD_HOST:+--statsd-host $STATSD_HOST:$STATSD_PORT} \
Expand Down
35 changes: 24 additions & 11 deletions bin/install-macosx_arm64
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
#!/bin/bash

# Install scripts for M1 Macs
# See https://github.com/PostHog/posthog/issues/2916
# NB: use cryptography==3.4.7
## NOTE: This is a helper script to simplify the process of getting setup on macOS. If in doubt check https://posthog.com/handbook/engineering/developing-locally

# Set ld flags to use OpenSSL installed with brew
export LDFLAGS="-L$(brew --prefix openssl)/lib"
export CPPFLAGS="-I$(brew --prefix openssl)/include"
set -e

# Use system OpenSSL instead of BoringSSL for GRPC
export GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1
export GRPC_PYTHON_BUILD_SYSTEM_ZLIB=1
echo "Attempting to install all dependencies and setup virtualenv..."
echo ""

pip cache purge
pip install -r requirements.txt
# Ensure we are in a directory ending with "posthog"
if [[ "$PWD" != *"/posthog" ]]; then
echo "Please run this script from a directory ending with 'posthog'"
exit 1
fi

if [[ $* == *--reset* ]]; then
rm -rf env/
fi

python3.10 -m venv env
source env/bin/activate

brew install openssl
CFLAGS="-I /opt/homebrew/opt/openssl/include $(python3.10-config --includes)" LDFLAGS="-L /opt/homebrew/opt/openssl/lib" GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1 GRPC_PYTHON_BUILD_SYSTEM_ZLIB=1 pip install -r requirements.txt

pip install -r requirements-dev.txt

echo ""
echo "🚀 Done!"
8 changes: 5 additions & 3 deletions bin/migrate-check
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/bin/bash
set -e

python manage.py migrate --check
python manage.py migrate_clickhouse --check
python manage.py run_async_migrations --check
if [ -z "$POSTHOG_SKIP_MIGRATION_CHECKS" ]; then
python manage.py migrate --check
python manage.py migrate_clickhouse --check
python manage.py run_async_migrations --check
fi
2 changes: 2 additions & 0 deletions cypress.e2e.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export default defineConfig({
// We've imported your old cypress plugins here.
// You may want to clean this up later by importing these.
setupNodeEvents(on, config) {
config.env.E2E_TESTING = !!process.env.E2E_TESTING

const options = {
webpackOptions: createEntry('cypress'),
watchOptions: {},
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/a11y.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('a11y', () => {
'persons',
'cohorts',
'annotations',
'plugins',
'apps',
'toolbarlaunch',
'projectsettings',
]
Expand Down
2 changes: 2 additions & 0 deletions cypress/e2e/dashboard-duplication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ describe('duplicating dashboards', () => {
let dashboardName, insightName, expectedCopiedDashboardName, expectedCopiedInsightName

beforeEach(() => {
cy.intercept('POST', /\/api\/projects\/\d+\/dashboards/).as('createDashboard')

dashboardName = randomString('dashboard-')
expectedCopiedDashboardName = `${dashboardName} (Copy)`

Expand Down
8 changes: 6 additions & 2 deletions cypress/e2e/events.cy.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { dayjs } from 'lib/dayjs'

const interceptPropertyDefinitions = (): void => {
cy.intercept('/api/event/values/?key=%24browser').as('getBrowserValues')

cy.intercept('api/projects/@current/property_definitions/?limit=5000', {
fixture: 'api/event/property_definitions',
})
Expand Down Expand Up @@ -71,8 +73,10 @@ describe('Events', () => {
cy.get('[data-attr=taxonomic-filter-searchfield]').click()
cy.get('[data-attr=prop-filter-event_properties-0]').click()
cy.get('[data-attr=prop-val] .ant-select-selector').click({ force: true })
cy.get('[data-attr=prop-val-0]').click()
cy.get('.DataTable').should('exist')
cy.wait('@getBrowserValues').then(() => {
cy.get('[data-attr=prop-val-0]').click()
cy.get('.DataTable').should('exist')
})
})

it('separates feature flag properties into their own tab', () => {
Expand Down
5 changes: 3 additions & 2 deletions cypress/e2e/featureFlags.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ describe('Feature Flags', () => {

// Check that feature flags instructions can be displayed in another code language
cy.get('[data-attr=feature-flag-instructions-select]').click()
cy.get('[data-attr=feature-flag-instructions-select-option-PHP]').click()
// force click rather than scrolling the element into view
cy.get('[data-attr=feature-flag-instructions-select-option-php]').click({ force: true })
cy.get('[data-attr=feature-flag-instructions-snippet]').should(
'contain',
/if (PostHog::isFeatureEnabled('.*', 'some distinct id')) {/
)
cy.get('[data-attr=feature-flag-instructions-snippet]').should('contain', / \/\/ do something here/)
cy.get('[data-attr=feature-flag-instructions-snippet]').should('contain', / {4}\/\/ do something here/)
cy.get('[data-attr=feature-flag-instructions-snippet]').should('contain', /}/)
cy.get('[data-attr=feature-flag-doc-link]').should(
'have.attr',
Expand Down
20 changes: 18 additions & 2 deletions cypress/e2e/insights-date-picker.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
import { decideResponse } from '../fixtures/api/decide'
import { urls } from 'scenes/urls'

describe('insights date picker', () => {
beforeEach(() => {
cy.intercept('https://app.posthog.com/decide/*', (req) =>
req.reply(
decideResponse({
hogql: true,
'data-exploration-insights': true,
})
)
)

cy.visit(urls.insightNew())
})

it('Can set the date filter and show the right grouping interval', () => {
cy.get('[data-attr=date-filter]').click()
cy.get('div').contains('Yesterday').should('exist').click()
cy.get('[data-attr=interval-filter]').should('contain', 'Hour')
cy.get('[data-attr=interval-filter] .LemonButton__content').should('contain', 'hour')
})

it('Can set a custom rolling date range', () => {
Expand All @@ -13,6 +29,6 @@ describe('insights date picker', () => {
cy.get('.RollingDateRangeFilter__label').should('contain', 'In the last').click()

// Test that the button shows the correct formatted range
cy.get('[data-attr=date-filter]').get('span').contains('Last 5 days').should('exist')
cy.get('[data-attr=date-filter]').get('.LemonButton__content').contains('Last 5 days').should('exist')
})
})
11 changes: 11 additions & 0 deletions cypress/e2e/insights-unsaved-confirmation.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ describe('Insights', () => {
)
)

// set window:confirm here to ensure previous tests can't block
cy.on('window:confirm', () => {
return true
})

cy.visit(urls.insightNew())
})

Expand Down Expand Up @@ -44,10 +49,13 @@ describe('Insights', () => {
})

insight.newInsight()

cy.log('Add series')
cy.get('[data-attr=add-action-event-button]').click()

cy.log('Navigate away')
cy.get('[data-attr="menu-item-featureflags"]').click()

cy.log('Save button should still be here because case 1 rejects confirm()')
cy.get('[data-attr="insight-save-button"]').should('exist')
})
Expand All @@ -56,9 +64,12 @@ describe('Insights', () => {
cy.on('window:confirm', () => {
return true
})

insight.newInsight()

cy.log('Add series')
cy.get('[data-attr=add-action-event-button]').click()

cy.log('Navigate away')
cy.get('[data-attr="menu-item-featureflags"]').click()
cy.url().should('include', '/feature_flags')
Expand Down
4 changes: 3 additions & 1 deletion cypress/e2e/insights.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ describe('Insights', () => {
describe('view source', () => {
it('can open the query editor', () => {
insight.newInsight('TRENDS')
cy.get('[aria-label="View source (BETA)"]').click()
insight.save()
cy.get('[data-attr="more-button"]').click()
cy.get('[data-attr="show-insight-source"]').click()
cy.get('[data-attr="query-editor"]').should('exist')
})
})
Expand Down
6 changes: 3 additions & 3 deletions cypress/e2e/notebooks-creation-and-deletion.cy.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { randomString } from '../support/random'

function visitNotebooksList(): void {
cy.clickNavMenu('dashboards')
cy.location('pathname').should('include', '/dashboard')
cy.get('h1').should('contain', 'Dashboards & Notebooks')
cy.clickNavMenu('notebooks')
cy.location('pathname').should('include', '/notebooks')
cy.get('h1').should('contain', 'Notebooks')
cy.get('li').contains('Notebooks').should('exist').click()
}

Expand Down
28 changes: 15 additions & 13 deletions cypress/e2e/notebooks.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,19 @@ describe('Notebooks', () => {

cy.fixture('api/notebooks/notebook.json').then((notebook) => {
cy.intercept('GET', /api\/projects\/\d+\/notebooks\/.*\//, { body: notebook }).as('loadNotebook')
// this means saving doesn't work but so what?
cy.intercept('PATCH', /api\/projects\/\d+\/notebooks\/.*\//, (req, res) => {
res.reply(req.body)
// bounce the notebook patch back as if it succeeded,
// this means saving doesn't work in Cypress but so what?
cy.intercept('PATCH', /api\/projects\/\d+\/notebooks\/.*\//, (req) => {
req.reply(req.body)
}).as('patchNotebook')
})

cy.clickNavMenu('dashboards')
cy.location('pathname').should('include', '/dashboard')
cy.clickNavMenu('notebooks')
cy.location('pathname').should('include', '/notebooks')
})

it('Notebooks are enabled', () => {
cy.get('h1').should('contain', 'Dashboards & Notebooks')
cy.get('h1').should('contain', 'Notebooks')
cy.get('li').contains('Notebooks').should('exist').click()
})

Expand All @@ -42,19 +43,20 @@ describe('Notebooks', () => {

it('Insertion suggestions can be dismissed', () => {
cy.visit(urls.notebook('h11RoiwV'))
cy.get('.node-ph-replay-timestamp').click()
cy.get('.NotebookEditor').type('{enter}')

cy.get('.NotebookRecordingTimestamp--preview').should('exist')
cy.get('.NotebookRecordingTimestamp.opacity-50').should('exist')

cy.get('.NotebookEditor').type('{esc}')
cy.get('.NotebookFloatingButton .LemonButton').should('exist')
cy.get('.NotebookRecordingTimestamp.opacity-50').should('not.exist')
})

it('Can comment on a recording', () => {
cy.visit(urls.replay())
cy.get('[data-attr="notebooks-replay-comment-button"]').click()
cy.get('[data-attr="notebooks-add-button"]').click()

cy.get('.LemonButton').contains('Comment in a new notebook').click()
cy.get('.LemonButton').contains('New notebook').click()

cy.get('.Notebook.Notebook--editable').should('be.visible')
cy.get('.ph-recording.NotebookNode').should('be.visible')
Expand All @@ -66,8 +68,8 @@ describe('Notebooks', () => {
cy.get('li').contains('Notebooks').should('exist').click()
cy.get('[data-attr="new-notebook"]').click()
// we don't actually get a new notebook because the API is mocked
// so, "exit" the timestamp block we start in
cy.get('.NotebookEditor').type('{esc}{enter}{enter}')
// so, we need to clear the text
cy.get('.NotebookEditor').type('{selectAll}{backSpace}{enter}')
})

it('Can add a number list', () => {
Expand All @@ -84,7 +86,7 @@ describe('Notebooks', () => {

it('Can add bold', () => {
cy.get('.NotebookEditor').type('**bold**')
cy.get('.NotebookEditor p').last().should('contain.html', '<strong>bold</strong>')
cy.get('.NotebookEditor p').first().should('contain.html', '<strong>bold</strong>')
})

it('Can add bullet list', () => {
Expand Down
Loading

0 comments on commit 4a2ebe2

Please sign in to comment.